【算法】折半搜索+数学计数

【题意】给定n个数(n<=20),定义一种方案为选择若干个数,这些数可以分成两个和相等的集合(不同划分方式算一种),求方案数(数字不同即方案不同)。

【题解】

考虑直接枚举集合的子集,再枚举子集的子集(划分方式),相当于将子集看成天平,枚举子集一些数置左,剩余数置右,则每个数有三种可能:不选,置左,置右。

由此可知,直接枚举集合子集的子集复杂度是O(3^n)。

考虑将总集划分成两半,则枚举一半的复杂度为O(3^(n/2))。

得到两半都如何合并?

如果相同集合不同划分方式算多种的话,可以将两半都unique,然后枚举一半的所有天平,在另一半二分找到相等天平,统计方案,复杂度O(3^(n/2)*log(3^(n/2))。

但是题目要求相同集合只算一次,如果仍然用上述方法则不能unique,因为相同集合只算一次,可以将方案标记到vis[],最后一次统计。但是没有unique的话二分就没有意义(如果全部数字相同仍需要全部扫描),复杂度O(3^n),显然超时。

考虑另一种方法,将一组数拿过去比较,两边两指针扫描,相等的标记到vis[]。这样有一个问题,就是左边拿来比较的数字不能有相同的数字,否则复杂度又不对了。

我们将左边的天平按选择的方案划分,即相同方案的一起处理,相同方案内相同的数字就可以舍去,不同的数字就两指针扫一遍,这样保证复杂度O(6^(n/2))。

总复杂度O(6^(n/2))。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct left{int v,from;}l[];
struct right{int v,s;}r[];
int n,first[],n0,ltot=,rtot=,a[],m,q[];
bool vis[];
void dfsl(int dep,int v,int s){
if(dep==n0){ltot++;l[ltot].v=v;l[ltot].from=first[s];first[s]=ltot;}
else{
dfsl(dep+,v,s);
dfsl(dep+,v+a[dep],s|(<<dep));
dfsl(dep+,v-a[dep],s|(<<dep));
}
}
void dfsr(int dep,int v,int s){
if(dep==n){rtot++;r[rtot].v=v;r[rtot].s=s;}
else{
dfsr(dep+,v,s);
dfsr(dep+,v+a[dep],s|(<<dep));
dfsr(dep+,v-a[dep],s|(<<dep));
}
}
bool cmp(right a,right b){return a.v<b.v;} int main()
{
scanf("%d",&n);
for(int i=;i<n;i++)scanf("%d",&a[i]);
n0=(n+)/;
dfsl(,,);//0~n0-1
dfsr(n0,,);//n0~n-1
sort(r+,r+rtot+,cmp);
for(int i=;i<(<<n0);i++){
m=;
for(int j=first[i];j;j=l[j].from)q[++m]=l[j].v;
sort(q+,q+m+);
int k=;
for(int j=;j<=rtot;j++){
while(k<=m&&q[k]<r[j].v)k++;
if(k>m)break;
if(q[k]==r[j].v)vis[r[j].s|i]=;
}
}
int ans=;
for(int i=;i<(<<n);i++){if(vis[i])ans++;}//细节:必须选数
printf("%d",ans);
return ;
}

【BZOJ】2679: [Usaco2012 Open]Balanced Cow Subsets的更多相关文章

  1. bzoj2679: [Usaco2012 Open]Balanced Cow Subsets(折半搜索)

    2679: [Usaco2012 Open]Balanced Cow Subsets Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 462  Solv ...

  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. 【BZOJ】1635: [Usaco2007 Jan]Tallest Cow 最高的牛

    [题意]n头牛,其中最高h.给定r组关系a和b,要求满足h[b]>=h[a]且a.b之间都小于min(h[a],h[b]),求第i头牛可能的最高高度. [算法]差分 [题解]容易发现r组关系只能 ...

  6. 【BZOJ】1666 [Usaco2006 Oct]Another Cow Number Game 奶牛的数字游戏

    [算法]贪心&&堆 [题解]反过来看就是合并任意两块木板,花费为木板长度之和. 显然从最小的两块开始合并即可,用堆(优先队列)维护. 经典DP问题石子归并是只能合并相邻两堆石子,所以不 ...

  7. 【BZOJ】1699 [Usaco2007 Jan]Balanced Lineup排队

    [算法]线段树 #include<cstdio> #include<cctype> #include<algorithm> using namespace std; ...

  8. 【BZOJ】3016: [Usaco2012 Nov]Clumsy Cows(贪心)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3016 之前yy了一个贪心,,,但是错了,,就是枚举前后对应的字符(前面第i个和后面第i个)然后相同答 ...

  9. 【BZOJ】1636: [Usaco2007 Jan]Balanced Lineup(rmq+树状数组)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1636 (我是不会说我看不懂题的) 裸的rmq.. #include <cstdio> # ...

随机推荐

  1. 数据库索引(结合B-树和B+树)

    数据库索引,是数据库管理系统中一个排序的数据结构以协助快速查询.更新数据库表中数据.索引的实现通常使用B树及其变种B+树. 在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种 ...

  2. css那些事儿2 盒子模型

    盒子模型是网页元素所占据页面窗口的矩形范围,是网页布局的核心基础之一,这里的盒子模型与我们平常收到的包裹类似. 一个包裹从内到外,分为真实物品部分,物品与外壳之间的填充区,外壳的厚度,当多个包裹放置在 ...

  3. 简单理解SQL Server锁机制

    多个用户同时对数据库的并发操作时,可能会遇到下面几种情况,导致数据前后不一致: 1,A.B事务同时对同一个数据进行修改,后提交的人的修改结果会破坏先提交的(丢失更新): 2,事务A修改某一条数据还未提 ...

  4. Visual C++中对运行时库的支持

    原文地址:http://blog.csdn.net/wqvbjhc/article/details/6612099 一.什么是C运行时库 1)C运行时库就是 C run-time library,是 ...

  5. html超出不自动换行

    1.使用overflow: hidden把超出的内容进行隐藏: 2.然后使用white-space: nowrap设置内容不换行: 3.最后使用text-overflow: ellipsis设置超出内 ...

  6. 使用Gulp实现网页自动刷新:gulp-connect

    入门指南 1. 全局安装 gulp: npm install --global gulp 2. 作为项目的开发依赖(devDependencies)安装: npm install --save-dev ...

  7. Struts2自定义结果视图(servlet验证码)

    1.编写一个类实现com.opensymphony.xwork2.Result,或者继承org.apache.struts2.dispatcher.StrutsResultSupport 2.自定义的 ...

  8. C++面向对象编程,继承,数据抽象,动态绑定

    派生类(derived class)能够继承基类(base class )定义的成员: 1).派生类可以无需改变而使用那些与派生类具体特性不相关的操作 2).可以重新定义那些与派生类相关的成员函数,将 ...

  9. BZOJ 1221 软件开发(费用流)

    容易看出这是显然的费用流模型. 把每天需要的餐巾数作为限制.需要将天数拆点,x’表示每天需要的餐巾,x’’表示每天用完的餐巾.所以加边 (s,x',INF,0),(x'',t,INF,0). 餐巾可以 ...

  10. hadoop中DataNode消失挂掉的原因及解决方法

    昨天在进行Hadoop实验时遇到一个问题,在sbin目录下输入jps命令,查看当前节点的状态时,意外发现DataNode节点不见了!!于是回忆了一下自己之前的操作过程,大概是因为将自己进入文件夹,将某 ...