2679: [Usaco2012 Open]Balanced Cow Subsets
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 462 Solved: 197
[Submit][Status][Discuss]
Description
Farmer John's owns N cows (2 <= N <= 20), where cow i produces M(i) units of milk each day (1 <= M(i) <= 100,000,000). FJ wants to streamline the process of milking his cows every day, so he installs a brand new milking machine in his barn. Unfortunately, the machine turns out to be far too sensitive: it only works properly if the cows on the left side of the barn have the exact same total milk output as the cows on the right side of the barn! Let us call a subset of cows "balanced" if it can be partitioned into two groups having equal milk output. Since only a balanced subset of cows can make the milking machine work, FJ wonders how many subsets of his N cows are balanced. Please help him compute this quantity.
给出N(1≤N≤20)个数M(i) (1 <= M(i) <= 100,000,000),在其中选若干个数,如果这几个数可以分成两个和相等的集合,那么方案数加1。问总方案数。
Input
Line 1: The integer N.
Lines 2..1+N: Line i+1 contains M(i).
Output
* Line 1: The number of balanced subsets of cows.
Sample Input
4 1 2 3 4
INPUT DETAILS: There are 4 cows, with milk outputs 1, 2, 3, and 4.
INPUT DETAILS: There are 4 cows, with milk outputs 1, 2, 3, and 4.
Sample Output
3
OUTPUT DETAILS: There are three balanced subsets: the subset {1,2,3}, which can be partitioned into {1,2} and {3}, the subset {1,3,4}, which can be partitioned into {1,3} and {4}, and the subset {1,2,3,4} which can be partitioned into {1,4} and {2,3}.
OUTPUT DETAILS: There are three balanced subsets: the subset {1,2,3}, which can be partitioned into {1,2} and {3}, the subset {1,3,4}, which can be partitioned into {1,3} and {4}, and the subset {1,2,3,4} which can be partitioned into {1,4} and {2,3}.
HINT
Source
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* 判断能否划分为两个相等集合时用dp RE了 */ #include<bits/stdc++.h> #define N 30 #define M 3111111 #define mod 2333333 using namespace std; int n,m,ans,cnt,flag; int a[N],vis[N],V[M]; int cur[N],sum[N]; inline int read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){if(x=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } bool dfs2(int cur[],int k,int val,int n) { if(n==2 && cur[1]!=cur[2]) return false; if(flag) return true; if(val==sum[n]-val) {flag=1;return true;} if(k==n && !flag) return false; for(int i=k+1;i<=n;i++) dfs2(cur,i,val+cur[i],n),dfs2(cur,i,val,n); if(!flag)return false; } bool judge() { int cnt_=0,S=1; memset(cur,0,sizeof cur); memset(sum,0,sizeof sum); for(int i=1;i<=n;i++) if(vis[i]) cur[++cnt_]=a[i],sum[cnt_]=sum[cnt_-1]+cur[cnt_]; sort(cur+1,cur+cnt_+1); for(int i=1;i<=cnt_;i++) S+=S*33+cur[i],S%=mod; if(V[S]) return false;V[S]=1;flag=0; if(sum[cnt_]%2) return false; if(dfs2(cur,0,0,cnt_)) return true; return false; } void dfs(int lim,int k,int tot) { if(tot==lim) { if(judge()) ans++; return; } if(k>n) return; for(int i=k+1;i<=n;i++) { if(vis[i]) continue; vis[i]=1;dfs(lim,k+1,tot+1); vis[i]=0; } } int main() { //freopen("ly.in","r",stdin); n=read(); for(int i=1;i<=n;i++) a[i]=read(); cnt=2; while(cnt<=n) { memset(vis,0,sizeof vis); dfs(cnt,0,0); cnt++; } printf("%d\n",ans); return 0; }