1. 程式人生 > >bzoj2679: [Usaco2012 Open]Balanced Cow Subsets

bzoj2679: [Usaco2012 Open]Balanced Cow Subsets

2679: [Usaco2012 Open]Balanced Cow Subsets

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 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.

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}.

HINT

 

Source

 

/*
判斷能否劃分為兩個相等集合時用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;
 }
24暴搜