【NOIP2016提高A组集训第4场11.1】平衡的子集
2016-11-02 17:31
323 查看
Description
夏令营有N个人,每个人的力气为M(i)。请大家从这N个人中选出若干人,如果这些人可以分成两组且两组力气之和完全相等,则称为一个合法的选法,问有多少种合法的选法?Solution
看到范围只有20,我已开始就打暴力,我以为可以快速判断是否合法,但是失败了。正解超级机智。
中途相遇法:首先把这20个数拆成两个数集,然后每个点有三个值-1,0,1,那么很明显就是-1就把这个数放到另一边,1就是放到这边,0表示不选。
那么暴力去搞这两个数集,只用O(2∗310)。
然后把这两个数组,按1、-1这些取出来的值排一次序,因为还要判重,所以每个选的情况还要打个二进制标记,然后两个指针同时去扫,就可以了。
Code
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<map> #include<vector> #define fo(i,a,b) for(i=a;i<=b;i++) #define fod(i,a,b) for(i=a;i>=b;i--) #define rep(i,a) for(i=first[a];i;i=next[i]) using namespace std; const int maxn=30,mo=1100007; int i,j,k,l,t,n,m,ans,xiao,da,r,num,op; int a[maxn],er[maxn]; int p[mo*2]; int first[mo*2],last[mo*2],next[mo*2],hou[mo*2],tou[mo*2]; bool bz[2025][2025]; int hash(int x){ int y=(x+mo*1000)%mo; while(p[y]!=op&&p[y]!=x)y=(y+1)%mo; return y; } void dfs(int x,int y,int z){ if(x==n/2+1){ k=hash(y); if(p[k]>=0){ t=hou[k]; next[t]=++num; last[num]=z; hou[k]=num; } else p[k]=y,hou[k]=++num,last[num]=z,tou[k]=num; return; } dfs(x+1,y,z); dfs(x+1,y+a[x],z+er[x-1]); dfs(x+1,y-a[x],z+er[x-1]); } void dfs1(int x,int y,int z){ if(x==n+1){ k=hash(y); if(p[k]==op)return; for(i=tou[k];i;i=next[i]){ if(!bz[z][last[i]]){ bz[z][last[i]]=1; ans++; } } return; } dfs1(x+1,y,z); dfs1(x+1,y+a[x],z+er[x-n/2-1]); dfs1(x+1,y-a[x],z+er[x-n/2-1]); } int main(){ freopen("subset.in","r",stdin); freopen("subset.out","w",stdout); // freopen("fan.in","r",stdin); scanf("%d",&n); fo(i,1,n)scanf("%d",&a[i]); memset(p,128,sizeof(p)); op=p[0]; er[0]=1; fo(i,1,10)er[i]=er[i-1]*2; dfs(1,0,0); dfs1(n/2+1,0,0); ans--; printf("%d\n",ans); }
相关文章推荐
- 平衡的子集 【NOIP2016提高A组集训第4场11.1】
- {题解}[jzoj4841]【NOIP2016提高A组集训第4场11.1】平衡的子集
- 【NOIP2016提高A组集训第4场11.1】平衡的子集
- 【JZOJ4841】【NOIP2016提高A组集训第4场11.1】平衡的子集
- JZOJ 4841【NOIP2016提高A组集训第4场】平衡的子集
- NOIP2016提高A组集训第4场11.1 总结
- 【JZOJ4840】【NOIP2016提高A组集训第4场11.1】小W砍大树
- JZOJ 4840. 【NOIP2016提高A组集训第4场11.1】小W砍大树
- 【JZOJ4860】【NOIP2016提高A组集训第7场11.4】分解数
- 禅与园林艺术【NOIP2016提高A组集训第8场11.5】
- 【JZOJ4878】【NOIP2016提高A组集训第10场11.8】时空传送
- 三部曲 【NOIP2016提高A组集训第16场11.15】
- JZOJ4887. 【NOIP2016提高A组集训第13场11.11】最大匹配
- JZOJ4899. 【NOIP2016提高A组集训第17场11.16】雪之国度
- JZOJ 4823. 【NOIP2016提高A组集训第1场10.29】小W学物理
- JZOJ4822. 【NOIP2016提高A组集训第1场10.29】完美标号
- 【NOIP2016提高A组集训第1场10.29】小W学物理
- 【NOIP2016提高A组集训第14场11.12】随机游走——期望+树形DP
- 【JZOJ4845】【NOIP2016提高A组集训第5场11.2】寻找
- 【JZOJ4861】【NOIP2016提高A组集训第7场11.4】推冰块