您的位置:首页 > 其它

ACDREAM 1726 A Math game(折半枚举+hash)

2015-05-10 10:34 309 查看
题目链接:

http://acdream.info/problem?pid=1726

题意:

给定n 个数,和一个数看,判断k能否由其中的任意个数的和组成。

 

分析:

因为n最大为40,暴力枚举所有的情况 复杂度为 2^40 肯定TLE ,然后就想到了折半枚举

分成两半,先处理前n/2个数的组合的情况 ,把所得结果哈希一下,然后再枚举后一半

的所有情况,然后在哈希表里查找。时间复杂度为 O(2^(N/2));

 

代码如下:

#include <stdio.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

#define PB push_back
#define MP make_pair
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,l,h) for(int i=(l);i<=(h);++i)
#define DWN(i,h,l) for(int i=(h);i>=(l);--i)
#define CLR(vis) memset(vis,0,sizeof(vis))
#define MST(vis,pos) memset(vis,pos,sizeof(vis))
#define MAX3(a,b,c) max(a,max(b,c))
#define MAX4(a,b,c,d) max(max(a,b),max(c,d))
#define MIN3(a,b,c) min(a,min(b,c))
#define MIN4(a,b,c,d) min(min(a,b),min(c,d))
#define PI acos(-1.0)
#define INF 1000000000
#define LINF 1000000000000000000LL
#define eps 1e-8
#define LL long long
using namespace std;

const int MAXN=1<<20;
const int HASH = 1000007;

struct hashmap//建立哈希表
{
LL a[MAXN];
int head[HASH],next[MAXN],size;
void init(){//初始化
MST(head,-1);
size=0;
}
bool find(LL val){//查找一个元素是否在哈希表内
int tmp = (val%HASH + HASH)%HASH;
for(int i = head[tmp];i!=-1;i=next[i])
if(val==a[i]) return true;
return false;
}
void add(LL val){//添加元素到哈希表中
int tmp =(val%HASH+HASH)%HASH;
if(find(val)) return;
a[size]=val;
next[size]=head[tmp];
head[tmp]=size++;
}
}h1;
int n,m,num[55];
int main()
{
while(~scanf("%d%d",&n,&m))
{
h1.init();
REP(i,n) scanf("%d",num+i);
int t=n/2;
REP(i,1<<t){
LL sum=0;
REP(j,t){
if(i&(1<<j))
sum+=num[j];
}
if(sum>m) continue;
h1.add(sum);
}
int tt=n-t;
int flag=0;
REP(i,1<<tt){
LL sum=0;
REP(j,tt){
if(i&(1<<j))
sum+=num[t+j];
}
if(sum>m)continue;
if(h1.find(m-sum)){
flag=1;
break;
}
}
if(flag)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: