BZOJ_2679_[Usaco2012 Open]Balanced Cow Subsets _meet in middle+双指针
2018-05-20 13:22
387 查看
BZOJ_2679_[Usaco2012 Open]Balanced Cow Subsets _meet in middle+双指针
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 4INPUT DETAILS: There are 4 cows, with milk outputs 1, 2, 3, and 4.
Sample Output
3
首先每个数的系数只可能是0,1,-1,并且1和-1都是选的状态。
用meet in middle的思想,$3^{n/2}$枚举左边和右边,把左边选或不选的状态与和挂链,右边按和排序。
枚举左边的状态,再枚举右边的和,枚举过程中左边指针单调。
然后统计答案即可。
复杂度$O(6^{n/2})$。
代码:
// luogu-judger-enable-o2 #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define mr(x,y) make_pair(x,y) #define N 100050 #define RR register #define O2 __attribute__((optimize("-O2"))) typedef long long ll; int n,a[25],m; int ans; int head ,to ,nxt ,cnt,tot,t ,vis[1<<22]; O2 struct A { int v,S; bool operator < (const A &x) const { return v<x.v; } }b ; O2 inline void add(int u,int v) { to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; } O2 void dfs(int dep,int sum,int sta) { if(dep==m+1) { add(sta,sum); return ; } dfs(dep+1,sum,sta); dfs(dep+1,sum+a[dep],sta|(1<<(dep-1))); dfs(dep+1,sum-a[dep],sta|(1<<(dep-1))); } O2 void solve(int dep,int sum,int sta) { if(dep==n+1) { b[++tot].v=sum; b[tot].S=sta; return ; } solve(dep+1,sum,sta); solve(dep+1,sum+a[dep],sta|(1<<(dep-1))); solve(dep+1,sum-a[dep],sta|(1<<(dep-1))); } O2 int main() { scanf("%d",&n); m=n/2; RR int i,j; for(i=1;i<=n;i++) scanf("%d",&a[i]); dfs(1,0,0); solve(m+1,0,0); sort(b+1,b+tot+1); for(i=0;i<(1<<m);i++) { t[0]=0; for(j=head[i];j;j=nxt[j]) { t[++t[0]]=to[j]; } sort(t+1,t+t[0]+1); RR int l=1,r=1; /*for(l=1;l<=t[0];l++) { while(r<=tot&&b[r].v<t[l]) r++; if(r==tot+1) break; if(b[r].v==t[l]) { vis[i|(b[r].S)]++; //if(vis[i|b[r].S]==1) ans++; } }*/ for(l=1;l<=tot;l++) { while(r<=t[0]&&t[r]<b[l].v) r++; if(r==t[0]+1) break; if(t[r]==b[l].v) { vis[i|(b[l].S)]++; if(vis[i|(b[l].S)]==1) ans++; } } } printf("%d\n",ans-1); }
相关文章推荐
- BZOJ 2679: [Usaco2012 Open]Balanced Cow Subsets meet_in_the_middle / 折半搜索
- BZOJ2679: [Usaco2012 Open]Balanced Cow Subsets
- bzoj 2679: [Usaco2012 Open]Balanced Cow Subsets 折半搜索
- 【BZOJ】2679: [Usaco2012 Open]Balanced Cow Subsets
- BZOJ2679 : [Usaco2012 Open]Balanced Cow Subsets
- BZOJ2679: [Usaco2012 Open]Balanced Cow Subsets
- [Meet In Middle] BZOJ 2679 [Usaco2012 Open]Balanced Cow Subsets
- 【折半搜索】BZOJ2679(Usaco2012 Open)[Balanced Cow Subsets]题解
- 【BZOJ】2679 [Usaco2012 Open]Balanced Cow Subsets 折半搜索+状压
- bzoj2679:[Usaco2012 Open]Balanced Cow Subsets
- JZOJ2935. 【USACO Open 2012 Gold Division】Balanced Cow Subsets
- [USACO 2012OPEN] Balanced Cow Subsets(meet in the middle + DFS)
- bzoj2679 [Usaco2012 Open]Balanced Cow Subsets折半搜索
- BZOJ1646: [Usaco2007 Open]Catch That Cow 抓住那只牛
- [bzoj3404] [Usaco2009 Open]Cow Digit Game又见数字游戏
- BZOJ 3404: [Usaco2009 Open]Cow Digit Game又见数字游戏(博弈论)
- bzoj3404 [Usaco2009 Open]Cow Digit Game又见数字游戏
- BZOJ 1646:[Usaco2007 Open]Catch That Cow 抓住那只牛
- bzoj 3377: [Usaco2004 Open]The Cow Lineup 奶牛序列
- bzoj3404 [Usaco2009 Open]Cow Digit Game又见数字游戏