题目链接:https://ac.nowcoder.com/acm/contest/889/D
题意:题意简单,从大小为36的集合中选若干元素使得他们的和为sum。
思路:第一感觉用搜索,复杂度为2^36,需要优化,正好用折半搜索。即在前一半枚举,并用map记录和,枚举后一半时查找是否存在前一半刚好满足两者的和为sum。
AC代码:
#include<cstdio> #include<algorithm> #include<iostream> #include<string> #include<map> using namespace std; typedef long long LL; int n; LL sum,a[40]; map<LL,string> mp; int main(){ scanf("%d%lld",&n,&sum); for(int i=0;i<n;++i) scanf("%lld",&a[i]); for(int i=0;i<(1<<n/2);++i){ string s; LL tmp=0; for(int j=0;j<n/2;++j) if((i>>j)&1){ tmp+=a[j]; s+='1'; } else{ s+='0'; } mp[tmp]=s; } for(int i=0;i<(1<<(n-n/2));++i){ string s; LL tmp=0; for(int j=0;j<n-n/2;++j) if((i>>j)&1){ tmp+=a[n/2+j]; s+='1'; } else{ s+='0'; } if(mp.count(sum-tmp)){ cout<<mp[sum-tmp]<<s<<" "; break; } } return 0; }