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=,f=;char c=getchar();
while(c>''||c<''){if(x=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} bool dfs2(int cur[],int k,int val,int n)
{
if(n== && cur[]!=cur[]) return false;
if(flag) return true;
if(val==sum[n]-val) {flag=;return true;}
if(k==n && !flag) return false;
for(int i=k+;i<=n;i++)
dfs2(cur,i,val+cur[i],n),dfs2(cur,i,val,n);
if(!flag)return false;
} bool judge()
{
int cnt_=,S=;
memset(cur,,sizeof cur);
memset(sum,,sizeof sum);
for(int i=;i<=n;i++) if(vis[i]) cur[++cnt_]=a[i],sum[cnt_]=sum[cnt_-]+cur[cnt_];
sort(cur+,cur+cnt_+);
for(int i=;i<=cnt_;i++) S+=S*+cur[i],S%=mod;
if(V[S]) return false;V[S]=;flag=;
if(sum[cnt_]%) return false;
if(dfs2(cur,,,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+;i<=n;i++)
{
if(vis[i]) continue;
vis[i]=;dfs(lim,k+,tot+);
vis[i]=;
}
} int main()
{
//freopen("ly.in","r",stdin);
n=read();
for(int i=;i<=n;i++) a[i]=read();
cnt=;
while(cnt<=n)
{
memset(vis,,sizeof vis);
dfs(cnt,,);
cnt++;
}
printf("%d\n",ans);
return ;
}

24暴搜

/*
折半搜索
枚举每个数如何选择,放入A就加,放入B就减
状压判断每个数的具体选择状态
最后双指针扫统计答案 若集合A的和 + 集合B的和为0那么就说明这两个集合构成的答案合法
*/
#include<bits/stdc++.h> #define N 22
#define ll long long using namespace std;
int n,v[N<<],maxdep,cnta,cntb;
bool vis[<<N];
ll ans;
struct node{
int state,x;
}a[<<N],b[<<N];
inline bool cmp1(node a,node b){return a.x<b.x;}
inline bool cmp2(node a,node b){return a.x>b.x;} inline int read()
{
int x=,f=;char c=getchar();
while(c>''||c<''){if(x=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
} void dfs(int dep,int sum,int now,int flag)
{
if(dep==maxdep+)
{
if(!flag)
a[++cnta].x=sum,a[cnta].state=now;
else
b[++cntb].x=sum,b[cntb].state=now;
return;
}
dfs(dep+,sum,now,flag);
dfs(dep+,sum+v[dep],now | (<<(dep-)),flag);
dfs(dep+,sum-v[dep],now | (<<(dep-)),flag);
}
int main()
{
n=read();
for(int i=; i<=n; i++)v[i]=read();
maxdep=n/;dfs(,,,);
maxdep=n; dfs(n/+,,,);
sort(a+,a++cnta,cmp1);
sort(b+,b++cntb,cmp2); int l=,r=;
while(l<=cnta&&r<=cntb)
{
while(-a[l].x<b[r].x&&r<=cntb)r++;
int pos=r;
while(r<=cntb&&-a[l].x==b[r].x)
{
if(!vis[a[l].state | b[r].state])
{
vis[a[l].state | b[r].state]=;
ans++;
}r++;
}
if(l<cnta&&a[l].x==a[l+].x)r=pos;
l++;
}
printf("%lld\n",ans-);//减去空集
return ;
}

bzoj2679: [Usaco2012 Open]Balanced Cow Subsets(折半搜索)的更多相关文章

  1. BZOJ2679 : [Usaco2012 Open]Balanced Cow Subsets

    考虑折半搜索,每个数的系数只能是-1,0,1之中的一个,因此可以先通过$O(3^\frac{n}{2})$的搜索分别搜索出两边每个状态的和以及数字的选择情况. 然后将后一半的状态按照和排序,$O(2^ ...

  2. 【BZOJ 2679】[Usaco2012 Open]Balanced Cow Subsets(折半搜索+双指针)

    [Usaco2012 Open]Balanced Cow Subsets 题目描述 给出\(N(1≤N≤20)\)个数\(M(i) (1 <= M(i) <= 100,000,000)\) ...

  3. BZOJ_2679_[Usaco2012 Open]Balanced Cow Subsets _meet in middle+双指针

    BZOJ_2679_[Usaco2012 Open]Balanced Cow Subsets _meet in middle+双指针 Description Farmer John's owns N ...

  4. 折半搜索+Hash表+状态压缩 | [Usaco2012 Open]Balanced Cow Subsets | BZOJ 2679 | Luogu SP11469

    题面:SP11469 SUBSET - Balanced Cow Subsets 题解: 对于任意一个数,它要么属于集合A,要么属于集合B,要么不选它.对应以上三种情况设置三个系数1.-1.0,于是将 ...

  5. bzoj2679:[Usaco2012 Open]Balanced Cow Subsets

    思路:折半搜索,每个数的状态只有三种:不选.选入集合A.选入集合B,然后就暴搜出其中一半,插入hash表,然后再暴搜另一半,在hash表里查找就好了. #include<iostream> ...

  6. [Usaco2012 Open]Balanced Cow Subsets

    Description Farmer John's owns N cows (2 <= N <= 20), where cow i produces M(i) units of milk ...

  7. 【BZOJ】2679: [Usaco2012 Open]Balanced Cow Subsets

    [算法]折半搜索+数学计数 [题意]给定n个数(n<=20),定义一种方案为选择若干个数,这些数可以分成两个和相等的集合(不同划分方式算一种),求方案数(数字不同即方案不同). [题解] 考虑直 ...

  8. SPOJ-SUBSET Balanced Cow Subsets

    嘟嘟嘟spoj 嘟嘟嘟vjudge 嘟嘟嘟luogu 这个数据范围都能想到是折半搜索. 但具体怎么搜呢? 还得扣着方程模型来想:我们把题中的两个相等的集合分别叫做左边和右边,令序列前一半中放到左边的数 ...

  9. BZOJ.2679.Balanced Cow Subsets(meet in the middle)

    BZOJ 洛谷 \(Description\) 给定\(n\)个数\(A_i\).求它有多少个子集,满足能被划分为两个和相等的集合. \(n\leq 20,1\leq A_i\leq10^8\). \ ...

随机推荐

  1. python接口自动化测试(一)

    本节开始,开始介绍python的接口自动化测试,首先需要搭建python开发环境,到https://www.python.org/下载python 版本直接安装就以了,建议 下载python2.7.1 ...

  2. git-svn 简易 操作指南

    git-svn 简易 操作指南 本文用以为使用svn的用户提供git操作指导,方便使用git管理用户自己的 本地修改 1:下载 库 下载全部历史记录 git svn clone svn://fhnws ...

  3. 慕课笔记利用css进行布局【混合布局练习】

    通过学习div的布局,以一个简单的内容管理网站的布局为例子,用div+css进行简单的网页布局,加深学印象: <html> <head> <title>CSS+di ...

  4. 1004. 成绩排名 (20) (快速排序qsort函数的使用问题)

    读入n名学生的姓名.学号.成绩,分别输出成绩最高和成绩最低学生的姓名和学号. 输入格式:每个测试输入包含1个测试用例,格式为 第1行:正整数n 第2行:第1个学生的姓名 学号 成绩 第3行:第2个学生 ...

  5. [luoguP1970] 花匠(DP)

    传送门 n2 过不了惨啊 70分做法 f[i][0] 表示第 i 个作为高的,的最优解 f[i][0] 表示第 i 个作为低的,的最优解 (且第 i 个一定选) 那么 f[i+1][1]=max(f[ ...

  6. Codeforces Round #259 (Div. 2) D

    D. Little Pony and Harmony Chest time limit per test 4 seconds memory limit per test 256 megabytes i ...

  7. HDU 4941

    Magical Forest Problem Description There is a forest can be seen as N * M grid. In this forest, ther ...

  8. 洛谷—— P1690 贪婪的Copy

    https://www.luogu.org/problem/show?pid=1690 题目描述 Copy从卢牛那里听说在一片叫yz的神的领域埋藏着不少宝藏,于是Copy来到了这个被划分为个区域的神地 ...

  9. Sql批量添加,批量查询,批量删除,批量修改。mybatis都有对应标签

    Sql批量添加,批量查询,批量删除,批量修改.mybatis都有对应标签

  10. 玩转iOS开发 - 消息推送

    消息推送