标签:
http://acdream.info/problem?pid=1726
10 87 2 3 4 5 7 9 10 11 12 13 10 38 2 3 4 5 7 9 10 11 12 13
No Yes
/** ACdreamOJ 1726 hash 题目大意:给定n个数,问这些数的部分和是否可以组成m 解题思路:由于n的最大值只有40,因此我们把所有的数分成均等的两部分,利用哈希查寻一下就可以了 */ #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> #include <queue> #include <map> using namespace std; typedef long long LL; const int MAXN=1<<20; const int HASH = 1000007; struct hashmap//建立哈希表 { LL a[MAXN]; int head[HASH],next[MAXN],size; void init() //初始化 { memset(head,-1,sizeof(head)); 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(); for(int i=0; i<n; i++) { scanf("%d",&num[i]); } int t=n/2; for(int i=0; i<(1<<t); i++) { LL sum=0; for(int j=0; j<t; j++) { if(i&(1<<j)) { sum+=num[j]; } } if(sum>m)continue; h1.add(sum); } int tt=n-t; int flag=0; for(int i=0; i<(1<<tt); i++) { LL sum=0; for(int j=0; j<tt; j++) { 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; }
标签:
原文地址:http://blog.csdn.net/lvshubao1314/article/details/45618845