[搜索] hdu 4016 Magic Bitwise And Operation

主题链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4016

Magic Bitwise And Operation

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 1315    Accepted Submission(s): 504


Problem Description
Given n integers, your task is to pick k out of them so that the picked number are minimum when do bitwise “AND” among all of them.
For example, there are three integers 5, 6 and 7. You are asked to pick two of them. Your possible strategy is (5, 6), (5, 7) or (6, 7). The values when do bitwise and all the picked numbers together are as follows:
5 and 6 = 4
5 and 7 = 5
6 and 7 = 6
The smallest one is 4.
 

Input
There are multiple test cases for this problem. The first line of the input contains an integer denoting the number of test cases.
  For each test case, there are two integers in the first line: n and k, denoting the number of given integers and the number of integers you are asked to pick out. n <= 40
  The second line contains the n integers. You may assume that all integers are small than 2^60.

Notes: There are about one thousand randomly generated test cases. Fortunately 90% of them are relatively small.
 

Output
For each test case, output only one integer is the smallest possible value.
 

Sample Input
 
   
3 3 2 5 6 7 8 2 238 153 223 247 111 252 253 247 40 10 1143632830316675007 558164877202423550 1152356080752164603 1143911006781551605 1132655005501751263 1152919305583327167 1141662230660382702 862439259920596463 1151777428397603327 1008771132016295871 855666336963428351 1151795583225167807 1152634943314572791 1071856693060561407 1132650872803426303 1124211056982081471 1152917106425982911 1152815392070041535 1080863910568853481 288230371856350975 1080720560532488126 864686455262281727 576460673919991167 574191342855241589 1152233760050118651 1152921504605798263 1152912708241186815 1079738008506187487 1075796261476483027 1080854478820730879 1152885219917823999 1151725162940854259 1147529498501577715 571956602920235519 1134545630643616248 1152921218991521790 1152921496000052703 1142788250826440703 1151654831778151421 1152780747522637695
 

Sample Output
 
   
Case #1: 4 Case #2: 9 Case #3: 36028797086245424
 

Source
 

Recommend
lcy   |   We have carefully selected several similar problems for you:   4017  4012  4013  4014  4015 


题目意思:

在n个数中找k个,使得这k个数相与的值最小。

解题思路:

搜索+剪枝

剪枝一:假设当前值和最后全部的值想与都小于当前求得的值的话,直接返回。由于与运算是越来越小的。

剪枝二:从小到大排序。搜索的顺序对得到最优值的时间有非常大影响。

代码:

//#include<CSpreadSheet.h>

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#include<cmath>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
//#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

#define Maxn 45
int n,k;
ll sa[Maxn],la[Maxn];
ll ans;

void dfs(int cur,int hav,ll now)
{
    if(hav==k)
    {
        if(ans==-1)
            ans=now;
        else if(now<ans)
            ans=now;
        return ;
    }
    if(cur>n)
        return ;
    if(ans!=-1&&(now&la[cur])>=ans)
        return ;
    dfs(cur+1,hav+1,now==-1?

sa[cur]:(now&sa[cur])); dfs(cur+1,hav,now); } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int t,cnt=0; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) scanf("%I64d",&sa[i]); sort(sa+1,sa+n+1); la[n]=sa[n]; for(int i=n-1;i>=1;i--) la[i]=la[i+1]&sa[i]; ans=-1; dfs(1,0,-1); printf("Case #%d: %I64d\n",++cnt,ans); } return 0; }



版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值