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
给出N(1≤N≤20)个数M(i) (1 <= M(i) <= 100,000,000),在其中选若干个数,如果这几个数可以分成两个和相等的集合,那么方案数加1。问总方案数。
Input
Output
Sample Input
INPUT DETAILS: There are 4 cows, with milk outputs 1, 2, 3, and 4.
Sample Output
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(折半搜索)的更多相关文章
- BZOJ2679 : [Usaco2012 Open]Balanced Cow Subsets
考虑折半搜索,每个数的系数只能是-1,0,1之中的一个,因此可以先通过$O(3^\frac{n}{2})$的搜索分别搜索出两边每个状态的和以及数字的选择情况. 然后将后一半的状态按照和排序,$O(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)\) ...
- 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 ...
- 折半搜索+Hash表+状态压缩 | [Usaco2012 Open]Balanced Cow Subsets | BZOJ 2679 | Luogu SP11469
题面:SP11469 SUBSET - Balanced Cow Subsets 题解: 对于任意一个数,它要么属于集合A,要么属于集合B,要么不选它.对应以上三种情况设置三个系数1.-1.0,于是将 ...
- bzoj2679:[Usaco2012 Open]Balanced Cow Subsets
思路:折半搜索,每个数的状态只有三种:不选.选入集合A.选入集合B,然后就暴搜出其中一半,插入hash表,然后再暴搜另一半,在hash表里查找就好了. #include<iostream> ...
- [Usaco2012 Open]Balanced Cow Subsets
Description Farmer John's owns N cows (2 <= N <= 20), where cow i produces M(i) units of milk ...
- 【BZOJ】2679: [Usaco2012 Open]Balanced Cow Subsets
[算法]折半搜索+数学计数 [题意]给定n个数(n<=20),定义一种方案为选择若干个数,这些数可以分成两个和相等的集合(不同划分方式算一种),求方案数(数字不同即方案不同). [题解] 考虑直 ...
- SPOJ-SUBSET Balanced Cow Subsets
嘟嘟嘟spoj 嘟嘟嘟vjudge 嘟嘟嘟luogu 这个数据范围都能想到是折半搜索. 但具体怎么搜呢? 还得扣着方程模型来想:我们把题中的两个相等的集合分别叫做左边和右边,令序列前一半中放到左边的数 ...
- BZOJ.2679.Balanced Cow Subsets(meet in the middle)
BZOJ 洛谷 \(Description\) 给定\(n\)个数\(A_i\).求它有多少个子集,满足能被划分为两个和相等的集合. \(n\leq 20,1\leq A_i\leq10^8\). \ ...
随机推荐
- jquery对JSON字符串的解析--eval函数
jquery eval解析JSON中的注意点介绍----https://www.jb51.net/article/40842.htm
- [K/3Cloud] 隐藏菜单后,如何在插件间接的调用隐藏菜单的操作
使用场景: 动态表单里面挂了个单据的序时薄,序时薄有菜单,但是把序时薄的工具栏隐藏了.新增,修改全部动态表单自己写.删除和过滤我想间接调用下隐藏的序时薄的删除和过滤按钮的操作.在插件里如何实现? 答: ...
- Uva - 12230 Crossing Rivers (数学期望)
你住在村庄A,每天需要过很多条河到另一个村庄B上班,B在A的右边,所有的河都在A,B之间,幸运的是每条船上都有自由移动的自动船, 因此只要到达河左岸然后等船过来,在右岸下船,上船之后船的速度不变.现在 ...
- [bzoj5343][Ctsc2018]混合果汁_二分答案_主席树
混合果汁 bzoj-5343 Ctsc-2018 题目大意:给定$n$中果汁,第$i$种果汁的美味度为$d_i$,每升价格为$p_i$,每次最多添加$l_i$升.现在要求用这$n$中果汁调配出$m$杯 ...
- codevs——1385 挤牛奶
1385 挤牛奶 USACO 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 青铜 Bronze 题解 查看运行结果 题目描述 Description 三个农民每天清 ...
- 深度学习——练习
对于深度学习的基础,线性回归以及逻辑回归,下面针对这两个方面做一个练习. 例子主要参考http://openclassroom.stanford.edu/MainFolder/CoursePage.p ...
- win7开启超级管理员账户(Administrator)
win7开启超级管理员账户(Administrator) 不同于XP系统,Windows7系统据说出于安全的考虑,将超级管理员帐户"Administrator"在登陆界面给隐藏了, ...
- 002 static and default route
r2(config)#ip route 192.168.1.0 255.255.255.0 192.168.2.1 r1(config)#ip route 192.168.3.0 255.255.25 ...
- [React] Build a slide deck with mdx-deck using Markdown + React
In this lesson we'll use mdx-deck to create a slide deck using Markdown and React. We'll look at add ...
- react 项目实战(二)创建 用户添加 页面 及 fetch请求 json-server db.json -w -p 8000
1.安装 路由 npm install -S react-router@3.x 2.新增页面 我们现在的应用只有一个Hello React的页面,现在需要添加一个用于添加用户的页面. 首先在/src目 ...