JZOJ 4841【NOIP2016提高A组集训第4场】平衡的子集
2016-11-02 17:24
381 查看
Description
夏令营有N个人,每个人的力气为M(i)。请大家从这N个人中选出若干人,如果这些人可以分成两组且两组力气之和完全相等,则称为一个合法的选法,问有多少种合法的选法?
Data Constraint
40%的数据满足:1<=M(i)<=1000;
对于100%的数据满足:2<=N<=20,1<=M(i)<=100000000
Solution
我们可以采用折半搜索。我们设一个人有三种状态:-1,0,1表示该人处在哪个队伍中或者不选。这样我们能算出前10个人能构出的所有和,然后我们将它的值存在一个哈希表里,同时该值向这10个人的二进制状态连一条边。再算后10个人时,直接在哈希表搜一下是否有相同的值即可。时间复杂度O(2∗310∗log310)。
代码
#include<iostream> #include<cmath> #include<cstring> #include<cstdio> #include<algorithm> #include<map> #define ll long long using namespace std; const int maxn=50,maxn1=1048580; int a[maxn],value[maxn1],er[maxn],h[maxn1][3],next[maxn1]; int n,i,t,j,k,l,x,sum,ans,p,num,q,q1; bool bz[1025][1025]; int hash(int x){ int t=(x+maxn1*1000)%maxn1; while (h[t][0]!=q1 && h[t][0]!=x) t=(t+1)%maxn1; return t; } void dg(int x,int y,int p){ if (x>n/2){ t=hash(y); if (h[t][0]>=0){ k=h[t][2]; next[k]=++num; value[num]=p; h[t][2]=num; }else h[t][1]=h[t][2]=++num,value[num]=p,h[t][0]=y; return; } dg(x+1,y,p); dg(x+1,y+a[x],p+er[x-1]); dg(x+1,y-a[x],p+er[x-1]); } void dg1(int x,int y,int p){ int t,k; if (x>n){ t=hash(y); if (h[t][1]==q1) return; for(k=h[t][1];k;k=next[k]) if (!bz[p][value[k]]) bz[p][value[k]]=true,ans++; return; } dg1(x+1,y,p); dg1(x+1,y+a[x],p+er[x-q]); dg1(x+1,y-a[x],p+er[x-q]); } int main(){ //freopen("subset.in","r",stdin);freopen("subset.out","w",stdout); freopen("data.in","r",stdin); scanf("%d",&n); for (i=1;i<=n;i++) scanf("%d",&a[i]); er[0]=1; for (i=1;i<=10;i++) er[i]=er[i-1]*2; memset(h,128,sizeof(h)); q1=h[0][0];q=n/2+1; dg(1,0,0); dg1(q,0,0); ans--; printf("%d\n",ans); }
相关文章推荐
- {题解}[jzoj4841]【NOIP2016提高A组集训第4场11.1】平衡的子集
- 平衡的子集 【NOIP2016提高A组集训第4场11.1】
- 【NOIP2016提高A组集训第4场11.1】平衡的子集
- 【JZOJ4841】【NOIP2016提高A组集训第4场11.1】平衡的子集
- 【NOIP2016提高A组集训第4场11.1】平衡的子集
- JZOJ 4840. 【NOIP2016提高A组集训第4场11.1】小W砍大树
- 【JZOJ4840】【NOIP2016提高A组集训第4场11.1】小W砍大树
- 【JZOJ4824】【NOIP2016提高A组集训第1场10.29】配对游戏
- JZOJ4880. 【NOIP2016提高A组集训第11场11.9】询问 (2017.10B组)
- 【JZOJ4859】【NOIP2016提高A组集训第7场11.4】连锁店
- JZOJ4884. 【NOIP2016提高A组集训第12场11.10】图的半径
- JZOJ 4867 【NOIP2016提高A组集训第8场11.5】心理学概论
- JZOJ4888【NOIP2016提高A组集训第14场11.12】最近公共祖先
- 【JZOJ4888】【NOIP2016提高A组集训第14场11.12】最近公共祖先
- 【JZOJ 4866】 【NOIP2016提高组集训】禅与园林艺术
- JZOJ 4883 【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰
- JZOJ4883. 【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰 2017.10(B组)
- JZOJ 4822 【NOIP2016提高A组集训第1场10.29】完美标号
- 【JZOJ4860】【NOIP2016提高A组集训第7场11.4】分解数
- 【JZOJ4901】【NOIP2016提高A组集训第18场11.17】矩阵