SPOJ-SUBSET Balanced Cow Subsets
嘟嘟嘟spoj
嘟嘟嘟vjudge
嘟嘟嘟luogu
这个数据范围都能想到是折半搜索。
但具体怎么搜呢?
还得扣着方程模型来想:我们把题中的两个相等的集合分别叫做左边和右边,令序列前一半中放到左边的数为\(a\),右边的数为\(b\),后一半同理为\(c\)和\(d\)。则我们要找的就是满足\(a + c = b + d\)的选取方案。
然后变形\(a - b = d - c\)。因此我们只要在前一半枚举\(a, b\),存起来,然后在后一半枚举\(c, d\),然后查找\(d - c\)是否出现过。
注意不是每一个数都要选,所以枚举的时候有三种情况:1.不选。2.选到左边。3.选到右边。所以复杂度为\(O(3 ^ {\frac{n}{2}})\)。
还有一点就是状态判重,这个用二进制表示就行。
具体实现就是用\(map\)离散化\(a - b\),然后因为\(a - b\)可能由好多种选取方案得来的,所以开一个\(vector\)记录每一个\(a - b\)对应的状态。统计答案的时候用一个\(bool\)数组判重即可。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<vector>
#include<stack>
#include<queue>
#include<map>
using namespace std;
#define enter puts("")
#define space putchar(' ')
#define Mem(a, x) memset(a, x, sizeof(a))
#define rg register
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 22;
const int maxp = 1.2e6 + 5;
inline ll read()
{
ll ans = 0;
char ch = getchar(), last = ' ';
while(!isdigit(ch)) last = ch, ch = getchar();
while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
if(last == '-') ans = -ans;
return ans;
}
inline void write(ll x)
{
if(x < 0) x = -x, putchar('-');
if(x >= 10) write(x / 10);
putchar(x % 10 + '0');
}
int n, m;
ll a[maxn];
int cnt = 0;
map<int, int> mp;
vector<int> v[maxp];
bool vis[maxp];
void dfs1(int stp, ll tot, int now)
{
if(stp > m)
{
if(mp.find(tot) == mp.end()) mp[tot] = ++cnt;
v[mp[tot]].push_back(now); return;
}
dfs1(stp + 1, tot, now);
dfs1(stp + 1, tot + a[stp], now + (1 << (stp - 1)));
dfs1(stp + 1, tot - a[stp], now + (1 << (stp - 1)));
}
void dfs2(int stp, ll tot, int now)
{
if(stp > n)
{
if(mp.find(tot) == mp.end()) return;
int id = mp[tot];
for(int i = 0; i < (int)v[id].size(); ++i) vis[v[id][i] | now] = 1;
return;
}
dfs2(stp + 1, tot, now);
dfs2(stp + 1, tot + a[stp], now + (1 << (stp - 1)));
dfs2(stp + 1, tot - a[stp], now + (1 << (stp - 1)));
}
int main()
{
n = read(); m = n >> 1;
for(int i = 1; i <= n; ++i) a[i] = read();
dfs1(1, 0, 0); dfs2(m + 1, 0, 0);
int ans = 0;
for(int i = 1; i < maxp; ++i) ans += (int)vis[i];
write(ans), enter;
return 0;
}
SPOJ-SUBSET Balanced Cow Subsets的更多相关文章
- 折半搜索+Hash表+状态压缩 | [Usaco2012 Open]Balanced Cow Subsets | BZOJ 2679 | Luogu SP11469
题面:SP11469 SUBSET - Balanced Cow Subsets 题解: 对于任意一个数,它要么属于集合A,要么属于集合B,要么不选它.对应以上三种情况设置三个系数1.-1.0,于是将 ...
- 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 ...
- bzoj2679: [Usaco2012 Open]Balanced Cow Subsets(折半搜索)
2679: [Usaco2012 Open]Balanced Cow Subsets Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 462 Solv ...
- 【BZOJ 2679】[Usaco2012 Open]Balanced Cow Subsets(折半搜索+双指针)
[Usaco2012 Open]Balanced Cow Subsets 题目描述 给出\(N(1≤N≤20)\)个数\(M(i) (1 <= M(i) <= 100,000,000)\) ...
- [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.Balanced Cow Subsets(meet in the middle)
BZOJ 洛谷 \(Description\) 给定\(n\)个数\(A_i\).求它有多少个子集,满足能被划分为两个和相等的集合. \(n\leq 20,1\leq A_i\leq10^8\). \ ...
- BZOJ2679 : [Usaco2012 Open]Balanced Cow Subsets
考虑折半搜索,每个数的系数只能是-1,0,1之中的一个,因此可以先通过$O(3^\frac{n}{2})$的搜索分别搜索出两边每个状态的和以及数字的选择情况. 然后将后一半的状态按照和排序,$O(2^ ...
- bzoj2679:[Usaco2012 Open]Balanced Cow Subsets
思路:折半搜索,每个数的状态只有三种:不选.选入集合A.选入集合B,然后就暴搜出其中一半,插入hash表,然后再暴搜另一半,在hash表里查找就好了. #include<iostream> ...
- 【BZOJ】2679: [Usaco2012 Open]Balanced Cow Subsets
[算法]折半搜索+数学计数 [题意]给定n个数(n<=20),定义一种方案为选择若干个数,这些数可以分成两个和相等的集合(不同划分方式算一种),求方案数(数字不同即方案不同). [题解] 考虑直 ...
随机推荐
- Java中接口的特点
Java接口在1.8之后发生了重大变化.所以谈Java接口特点可以分为1.8版本之前和1.8版本之后. 1.8版本之前的特点: 接口里只能有静态全局常量和public修饰的抽象方法. 为了代码简洁,在 ...
- 第二节:Java开发环境的搭建
一.认识并安装JDK 1.JDK(Java Development Kit)是Java开发工具集,包括Java运行环境(JRE).Java开发工具以及一些基础类库,进行Java开发所必须安装的软件. ...
- golang使用graphviz
graphviz的介绍请参考: http://www.cnblogs.com/ghj1976/p/4539788.html 安装 graphviz 需要在 http://www.graphviz.o ...
- WPF流程图制作系列相关基础一
WPF流程图制作相关基础一 需求是要通过wpf开发流程图,这个流程图是用户自行拖动配置. 使用过流程图的话,应该大体能想象出流程图拖动配置的样子.这里主要会涉及到的技术知识点就是 wpf拖动相 ...
- 适配器(GOF23)
---恢复内容开始--- 摘要:由于应用环境的变化,需要将现存的对象放到新的环境中去,但新环境的接口是现存对象不满足的. 意图:将原本接口不兼容的类通过转换,使得它们能够一起工作,复用现有的类 ada ...
- CSS reset的审视
by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=758 一.CSS re ...
- webpack打包遇到过的问题
1.打包后html文件打开是空白页面,报错信息如图所示: 解决办法:这里主要是将assetsPublicPath的路径从'/'改为'./'就好了. ('/'表示根目录:'./'表示当前目录) 2.运行 ...
- 新电脑装不了win7?来试试我的方法!
好久没写日记了,今天稍有时间来写个有关于硬件的技术贴. 前段时间换了个惠普暗影精灵二代,它的cpu代数如图所示: 用了几天系统自带win10,不同浏览器字体模糊的问题是个问题,故而想装 ...
- JSP 插入到数据库的数据出现 “SQLServerException: 将截断字符串或二进制数据” 错误解决方案
最近在编写一个小型基于的jsp系统开发.掌握数据库一直感觉还不错.但是今天就出现了一个问题困扰我大半天.后来本来准备睡觉,但是觉得今天不解决这个问题恐怕晚上是“彻夜难眠啊”!!于是打开电脑,又开始捣腾 ...
- content-box与border-box区别
理解box-sizing属性border-box,content-box,其实也是理解正常盒模型与异常盒模型. 正常盒模型 正常盒模型,是指块元素box-sizing属性为content-box的盒模 ...