jzoj4841 平衡的子集
2016-12-05 18:16
218 查看
问题描述
有n个数,问有多少种从其中选若干个数的合法方案。一个合法方案是指,选出来的数可以分为两组,使得两组之和相等。
对于100%的数据满足:2<=N<=20,1<=a[i]<=100000000
解
一开始还理解错题意了(2次),一开始以为是所有数都要分组,然后以为问的是有多少种分组方案使得和相等。看到20想到的就是状压和折半搜索(Alan给我们口胡的那个东西)。
先把20个数分成两半。
我们显然可以知道,如果一边选的和是l,r,另一边选的和是ll,rr,那么当l-r=ll-rr时,这可以拼成一种合法的方案。
于是我们暴搜一边,存下一个差x的所有可能选法(要判重,不然理论时间过不了)。对于一种选法可能会有210种差,总共会有210种选法,于是总共可能会有4^10种。
对于另外一边,我们每找到一个差y,去找对应的差x’=y,然后枚举x’的所有可能状态,合并判重。这一步的时间复杂度是O(3n∗2n)=O(6n),因为对于一种差最多有2n次方种选法。
不带判重水过的
#include <cstdio> #include <iostream> #include <cstring> #define maxn 21 #define mo 9000007 #define lim 4000000000LL typedef long long ll; using namespace std; struct hashMap{ ll ht[mo]; ll hash(ll x) { int rt=x%mo; while (ht[rt]!=-lim && ht[rt]!=x) { rt++; if (rt>=mo) rt=0; } ht[rt]=x; return rt; } hashMap() { for (int i=1; i<mo; i++) ht[i]=-lim; } } h; int n,a[maxn],mid,tmpl; int tot,head[mo],next[mo],bit[mo]; int cnted[2000][2000]; ll ans; void link(int x,int y) { bit[++tot]=y; next[tot]=head[x]; head[x]=tot; } void dfs(int x,ll l,ll r,ll st) { if (x==mid+1) { if (l-r<0) return; tmpl=h.hash(l-r); link(tmpl,st); return; } dfs(x+1,l,r,st<<1); dfs(x+1,l+a[x],r,(st<<1)+1); dfs(x+1,l,r+a[x],(st<<1)+1); } int k; void dfs2(int x,ll l,ll r,ll st) { if (x==mid) { if (l-r<0) return; k=h.hash(l-r); for (int i=head[k]; i; i=next[i]) { if (cnted[bit[i]][st]==0) { cnted[bit[i]][st]=1; ans++; } } return; } dfs2(x-1,l,r,st<<1); dfs2(x-1,l+a[x],r,(st<<1)+1); dfs2(x-1,l,r+a[x],(st<<1)+1); } int main() { freopen("subset.in","r",stdin); freopen("subset.out","w",stdout); cin>>n; for (int i=1; i<=n; i++) scanf("%d",&a[i]); mid=n/2; dfs(1,0,0,0); dfs2(n,0,0,0); cout<<ans-1<<endl; }
相关文章推荐
- JZOJ4841 平衡的子集
- [JZOJ4841] 平衡的子集
- 【JZOJ 4841】平衡的子集
- {题解}[jzoj4841]【NOIP2016提高A组集训第4场11.1】平衡的子集
- JZOJ 4841【NOIP2016提高A组集训第4场】平衡的子集
- 【JZOJ 4841】平衡的子集 口胡题解
- Jzoj4841 平衡的子集
- jzoj 1278. 排队 洛谷 P2880 [USACO07JAN]平衡的阵容Balanced Lineup
- 【JSOI2015】【JZOJ 4058】子集选取
- [后缀平衡树][JZOJ4384]hashit
- JZOJ 4058. 【JSOI2015】子集选取
- 【JZOJ4841】平衡的子集
- [JZOJ4058]【JSOI2015】子集选取
- 【JZOJ4841】【NOIP2016提高A组集训第4场11.1】平衡的子集
- 【NOIP2016提高A组集训第4场11.1】平衡的子集
- 【NOIP2016提高A组集训第4场11.1】平衡的子集
- JZOJ4828. 【GDOI2017模拟10.30】最大值 分类讨论+分治处理子集问题
- 【jzoj4841】【平衡的子集】【搜索】
- 平衡的子集 【NOIP2016提高A组集训第4场11.1】
- 设二叉排序树已经以二叉链表得形式存储在内存中,使用递归算法求各节点的平衡因子。