主题链接:
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
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.
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.
在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; }
版权声明:本文博客原创文章,博客,未经同意,不得转载。