标签:
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