Description

给n个数,从中任意选出一些数,使这些数能分成和相等的两组。

求有多少种选数的方案。

Input

第\(1\)行:一个整数\(N\)

第\(2\)到\(N+1\)行,包含一个整数\(m_i\)

Output

一行:平衡的集合的个数.

看到题的一瞬间数据范围?

\(N \leq 20?\)状压!

明显直接做过不去,选择折半搜索.

折半搜索的话会有三种情况

  • 一.选择当前位置
  • 二.选择当前位置,给第一组.
  • 三.选择当前位置,给第二组.

然后直接跑折半搜索+状压即可.

存储类似链式前向星,应该不是很难理解,就不过多解释了.

然后就枚举状态即可,可是直接枚举到\(2^n-1\)显然会\(T\)掉.

由于我们后半截的状态已知,所以说,我们只需要枚举前一半的状态即可.

注意要\(sort\)找到两边力气值相等的.

其他的就不太难理解了,如果不能理解的话可以私信我 qwq.

代码

#include<cstdio>
#include<cctype>
#include<algorithm>
#define N 10000008
#define R register
using namespace std;
inline void in(int &x)
{
int f=1;x=0;char s=getchar();
while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
while(isdigit(s)){x=x*10+s-'0';s=getchar();}
x*=f;
}
int n,w[28],mid,head[N];
struct cod{int u,val;}e[200008],edge[N];
int v[N],ans,tot,ttt,sta,cnt;
bool vis[2500000];
void dfs1(int dep,int sum,int state)
{
if(dep>mid)
{
edge[++tot].u=head[state];
edge[tot].val=sum;
head[state]=tot;
return;
}
dfs1(dep+1,sum,state);
dfs1(dep+1,sum+w[dep],state|(1<<(dep-1)));
dfs1(dep+1,sum-w[dep],state|(1<<(dep-1)));
}
void dfs2(int dep,int sum,int state)
{
if(dep>n)
{
e[++ttt].u=state;
e[ttt].val=sum;
return;
}
dfs2(dep+1,sum,state);
dfs2(dep+1,sum+w[dep],state | (1<<(dep-1)));
dfs2(dep+1,sum-w[dep],state | (1<<(dep-1)));
}
inline bool ccp(const cod&a,const cod&b)
{
return a.val<b.val;
}
int main()
{
in(n);mid=(n+1)>>1;sta=(1<<n)-1;
for(R int i=1;i<=n;i++)in(w[i]);
dfs1(1,0,0);dfs2(mid+1,0,0);
sort(e+1,e+ttt+1,ccp);
for(R int i=0;i<=(1<<mid);i++)
{
R int cnt=0;
for(R int j=head[i];j;j=edge[j].u)
v[++cnt]=edge[j].val;
sort(v+1,v+cnt+1);
R int pos=1;
if(v[1]>e[ttt].val)break;
for(R int j=1;j<=ttt;j++)
{
while(pos<=cnt and v[pos]<e[j].val)pos++;
if(pos>cnt)break;
if(v[pos]==e[j].val)
vis[i|e[j].u]=true;
}
}
for(R int i=1;i<=sta;i++)
if(vis[i])ans++;
printf("%d",ans);
}
/*
10
5 8 16 17 25 83 24 7 8 20 89
*/

折半搜索+状态压缩【P3067】 [USACO12OPEN]平衡的奶牛群Balanced Cow S…的更多相关文章

  1. 洛谷 P3067 [USACO12OPEN]平衡的奶牛群Balanced Cow S…

    P3067 [USACO12OPEN]平衡的奶牛群Balanced Cow S… 题目描述 Farmer John's owns N cows (2 <= N <= 20), where ...

  2. [luogu3067 USACO12OPEN] 平衡的奶牛群

    传送门 Solution 折半搜索模板题 考虑枚举每个点在左集合和右集合或者不在集合中,然后排序合并即可 Code //By Menteur_Hxy #include <cmath> #i ...

  3. POJ 2046 Gap 搜索- 状态压缩

    题目地址: http://poj.org/problem?id=2046 一道搜索状态压缩的题目,关键是怎样hash. AC代码: #include <iostream> #include ...

  4. P3067 [USACO12OPEN]平衡的奶牛群(折半暴搜)

    暴搜无疑.... 首先考虑纯暴搜...... 考虑每一个数: 选在左边集合 选在右边集合 不选 一共三种情况,用一个数组记录搜到的答案,所以暴搜是3^N的复杂度...直接死亡 于是讲折半暴搜.... ...

  5. HDU-5025 Saving Tang Monk 广度搜索 状态压缩

    题目链接:https://cn.vjudge.net/problem/HDU-5025 题意 救唐僧,路上有m(<=9)把钥匙,最多5条蛇和一个唐僧. 目标是前往唐僧的地方,用全部钥匙打开全部的 ...

  6. Luogu3067 平衡的奶牛群 Meet in the middle

    题意:给出$N$个范围在$[1,10^8]$内的整数,问有多少种取数方案使得取出来的数能够分成两个和相等的集合.$N \leq 20$ 发现爆搜是$O(3^N)$的,所以考虑双向搜索. 先把前$3^\ ...

  7. Doing Homework---hdu1074(状态压缩&&记忆化搜索)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1074 有n(n<=15)门课需要做作业,每门课所需时间是used_time以及每门课作业上交的最 ...

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

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

  9. loj 1011(状态压缩+记忆化搜索)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25837 思路:状态压缩+记忆化搜索. #include<io ...

随机推荐

  1. 【C++ 拾遗】Function-like Macros

    Macro expansion is done by the C preprocessor at the beginning of compilation. The C preprocessor is ...

  2. error C3872: '0x3000': this character is not allowed in an identifier 解决方法

    文章参考地址:http://blog.csdn.net/danxuezx/article/details/5096497 编译时遇到这个错误多半是从网上拷贝一段代码到VS里然后编译时产生的,这是因为拷 ...

  3. Phaser的timer用法

    1. 延迟timer,相当于setTimeout game.time.events.add(Phaser.Timer.SECOND*5,this.delayOver,this); 2. 循环timer ...

  4. BZOJ_day9

    哇,一道巨大的水题害得我wa了无数次... 总结一下教训 大家一定记住(给我自己看的)  位运算 一定要加()!!! 重要的事情说三遍  位运算 一定要加()!!! 位运算 一定要加()!!! 位运算 ...

  5. Spring源码解析-事件

    Spring事件的组件 主要是3个组件: 1.ApplicationEvent   事件 2.ApplicationListener 监听器,对事件进行监听 3.ApplicationEventMul ...

  6. poj 1523 割点 tarjan

    Description Consider the two networks shown below. Assuming that data moves around these networks on ...

  7. angular js 自定义添加依赖

    代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  8. oracle的rownum使用

    对于rownum来说它是Oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数,且rownum不能以任何表的名称作为前缀. ...

  9. tomcat内存配置(二)

    Tomcat本身不能直接在计算机上运行,需要依赖于硬件基础之上的操作系统和一个Java虚拟机.Tomcat的内存溢出本质就是JVM内存溢出,所以在本文开始时,应该先对JavaJVM有关内存方面的知识进 ...

  10. JS模块化工具requirejs教程02

    基本API require会定义三个变量:define,require,requirejs,其中require === requirejs,一般使用require更简短 define 从名字就可以看出 ...