Luogu3067 平衡的奶牛群 Meet in the middle
题意:给出$N$个范围在$[1,10^8]$内的整数,问有多少种取数方案使得取出来的数能够分成两个和相等的集合。$N \leq 20$
发现爆搜是$O(3^N)$的,所以考虑双向搜索。
先把前$3^\frac{N}{2}$搜完,然后每一次搜出后$3^\frac{N}{2}$的时候,枚举前面的$2^\frac{N}{2}$,每一个对应一下看有没有和为$0$的方案即可。复杂度为$O(6^\frac{N}{2})$,虽然不开O2过不去qwq
#include<bits/stdc++.h>
using namespace std;
inline int read(){
;
char c = getchar();
while(!isdigit(c))
c = getchar();
while(isdigit(c)){
a = (a << ) + (a << ) + (c ^ ');
c = getchar();
}
return a;
}
struct HashTable{
#define MOD 103
struct node{
int num;
node* nxt;
}*begin[MOD] , *last[MOD];
void insert(int num){
int t = num % MOD;
)
t += MOD;
if(last[t] == NULL){
begin[t] = new node;
begin[t]->num = num;
begin[t]->nxt = NULL;
last[t] = begin[t];
}
else{
node* now = new node;
now->num = num;
now->nxt = NULL;
last[t]->nxt = now;
last[t] = now;
}
}
bool count(int num){
int t = num % MOD;
)
t += MOD;
for(node* i = begin[t] ; i != NULL ; i = i->nxt)
if(i->num == num)
;
;
}
}zt[ << ];
] , N , ans;
<< ][ << ];
void init(int now , int end , int cnt , int sum){
if(now > end){
zt[cnt].insert(sum);
return;
}
init(now + , end , cnt , sum);
init(now + , end , cnt | ( << now) , sum + M[now]);
init(now + , end , cnt | ( << now) , sum - M[now]);
}
void getAns(int now , int end , int cnt , int sum){
if(now > end){
; i < << (N >> ) ; i++)
if(!is[cnt][i] && (zt[i].count(sum) || zt[i].count(-sum))){
;
ans++;
}
return;
}
getAns(now + , end , cnt , sum);
getAns(now + , end , cnt | ( << now - (N >> )) , sum + M[now]);
getAns(now + , end , cnt | ( << now - (N >> )) , sum - M[now]);
}
int main(){
N = read();
; i < N ; i++)
M[i] = read();
init( , (N >> ) - , , );
getAns(N >> , N - , , );
cout << ans - ;
;
}
再放一个复杂度似乎不对但是很快的方法
#include<bits/stdc++.h>
using namespace std;
struct node{
int zt , sum;
}num1[] , num2[];
];
];
void dfs(node* num , int& cnt , int now , int end , int sum , int zt){
if(now > end){
num[++cnt].sum = sum;
num[cnt].zt = zt;
return;
}
dfs(num , cnt , now + , end , sum , zt);
dfs(num , cnt , now + , end , sum + M[now] , zt | ( << now));
dfs(num , cnt , now + , end , sum - M[now] , zt | ( << now));
}
bool cmp(node a , node b){
return a.sum < b.sum;
}
bool operator == (node a , node b){
return a.zt == b.zt && a.sum == b.sum;
}
int main(){
cin >> N;
; i < N ; i++)
cin >> M[i];
dfs(num1 , cnt1 , , (N - ) >> , , );
dfs(num2 , cnt2 , N >> , N - , , );
sort(num1 + , num1 + cnt1 + , cmp);
sort(num2 + , num2 + cnt2 + , cmp);
cnt1 = unique(num1 + , num1 + cnt1 + ) - num1 - ;
cnt2 = unique(num2 + , num2 + cnt2 + ) - num2 - ;
int p1 = cnt2 , p2 = cnt2;
; i <= cnt1 ; i++){
)
p1--;
p2 = p1;
)
p2--;
while(++p2 <= p1)
vis[num1[i].zt | num2[p2].zt] = ;
}
;
; i < << N ; i++)
ans += vis[i];
cout << ans;
;
}
Luogu3067 平衡的奶牛群 Meet in the middle的更多相关文章
- 洛谷 P3067 [USACO12OPEN]平衡的奶牛群Balanced Cow S…
P3067 [USACO12OPEN]平衡的奶牛群Balanced Cow S… 题目描述 Farmer John's owns N cows (2 <= N <= 20), where ...
- [luogu3067 USACO12OPEN] 平衡的奶牛群
传送门 Solution 折半搜索模板题 考虑枚举每个点在左集合和右集合或者不在集合中,然后排序合并即可 Code //By Menteur_Hxy #include <cmath> #i ...
- 折半搜索+状态压缩【P3067】 [USACO12OPEN]平衡的奶牛群Balanced Cow S…
Description 给n个数,从中任意选出一些数,使这些数能分成和相等的两组. 求有多少种选数的方案. Input 第\(1\)行:一个整数\(N\) 第\(2\)到\(N+1\)行,包含一个整数 ...
- Meet in the middle
搜索是\(OI\)中一个十分基础也十分重要的部分,近年来搜索题目越来越少,逐渐淡出人们的视野.但一些对搜索的优化,例如\(A\)*,迭代加深依旧会不时出现.本文讨论另一种搜索--折半搜索\((meet ...
- Meet in the middle学习笔记
Meet in the middle(MITM) Tags:搜索 作业部落 评论地址 PPT中会讲的很详细 当搜索的各项互不影响(如共\(n\)个物品前\(n/2\)个物品选不选和后\(n/2\)个物 ...
- SPOJ4580 ABCDEF(meet in the middle)
题意 题目链接 Sol 发现abcdef是互不相关的 那么meet in the middle一下.先算出abc的,再算def的 注意d = 0的时候不合法(害我wa了两发..) #include&l ...
- codevs1735 方程的解数(meet in the middle)
题意 题目链接 Sol 把前一半放在左边,后一半放在右边 meet in the middle一波 统计答案的时候开始想的是hash,然而MLE了两个点 实际上只要排序之后双指针扫一遍就行了 #inc ...
- 【BZOJ4800】[Ceoi2015]Ice Hockey World Championship (meet in the middle)
[BZOJ4800][Ceoi2015]Ice Hockey World Championship (meet in the middle) 题面 BZOJ 洛谷 题解 裸题吧,顺手写一下... #i ...
- 【CF888E】Maximum Subsequence(meet in the middle)
[CF888E]Maximum Subsequence(meet in the middle) 题面 CF 洛谷 题解 把所有数分一下,然后\(meet\ in\ the\ middle\)做就好了. ...
随机推荐
- 关于input的焦点事件
关于input的焦点事件 $(".scanf_integral").focus(function(){//获取焦点//获取焦点后触发的事件 }) $(".scanf_in ...
- Angular基础(二) 组件的使用
一.简单操作 a) 使用Angular CLI可以快速创建项目框架,先运行 $ npm install –g @angular/cli@1.0.0安装CLI,为CLI的位置设置环境变量,然后就可以 ...
- Expect 安装 on centos7
本文演示如何在CentOS7上安装和使用Expect. 使用场景 在主机A上编写并且执行Shell脚本,Shell脚本中需要ssh到主机B上执行交互命令. 安装 在主机A上安装expect: yum ...
- Python实现批量梯度下降算法
# -*- coding: UTF-8 -*- import numpy as npimport math # 定义基础变量learning_rate = 0.1n_iterations = 1000 ...
- [20180730]exadata与行链接.txt
[20180730]exadata与行链接.txt --//最近一段时间在看<expert oracle exadata>,智能扫描的三大优化方法是:字段投影,谓词过滤,存储索引.大多数智 ...
- charles系列破解激活办法(最高charles4.2都可以激活)
// Charles Proxy License // 适用于Charles任意版本的注册码,谁还会想要使用破解版呢. // Charles 4.2目前是最新版,可用. Registered Na ...
- 统计分页一些sql
USE [QPTreasureDB] GO /****** Object: StoredProcedure [dbo].[GameStatistics] Script Date: 2018/8/16 ...
- 面向对象的封装与隐藏 this
当我们创建一个对象的时候,我们可以通过‘对象.属性’的方式,对对象的属性进行赋值. 这里赋值操作要受到属性的数据类型和存储范围的制约,但是除此之外,没有其他制约条件. 但是实际问题中我们需要给这个属性 ...
- centos 6.5下安装nmap工具及简单用法
Nmap是一款针对大型网络的端口扫描工具,被广泛应用于黑客领域做漏洞探测以及安全扫描,其主要功能有主机发现(Host Discovery). 端口扫描(Port Scanning). 版本侦测(Ver ...
- Python基础知识:函数
1.定义函数和调用函数 #定义函数def def greet_user(username): '''简单的问候语''' print('Hello,%s!'%username) greet_user(' ...