Calculation(dfs+状压dp)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int dp[ << ];
int a[];
int n, S;
void dfs(int i, int val, int cur){
if(i == n){
if(val == S){
dp[cur] = ;
}
return;
}
dfs(i + , val, cur);
dfs(i + , val + a[i], cur | ( << i));
dfs(i + , val - a[i], cur | ( << i));
}
int main(){
int T;
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &S);
for(int i = ; i < n; i++){
scanf("%d", a + i);
}
fill(dp, dp + ( << n), );
dfs(, , );
for (int i = ; i < ( << n); i++){
for (int j = i & (i - ); j > ; j = i & (j - )){
dp[i] = max(dp[i], dp[j] + dp[j ^ i]);
//j是i的子集,j ^ i 是i的补集;
}
}
printf("%d\n", dp[( << n) - ]);
}
return ;
}
学长说还可以用中途对撞写,那样可以把dfs时间复杂度降到O(n*3^(n / 2)):
学长的中途对撞:
int d[ << ];
int a[];
int n, s; void MakeSum(const vector<int> &x, vector< pair<int, int> > &res) {
for (int i = ; i < ( << x.size()); ++i) {
int cur = ;
for (int j = ; j < x.size(); ++j) {
if (i >> j & ) cur -= x[j];
}
res.push_back(make_pair(cur, i));
for (int j = i; j > ; j = (j - ) & i) {
cur = ;
for (int k = ; k < x.size(); ++k) {
if (i >> k & ) {
if (j >> k & ) cur += x[k];
else cur -= x[k];
}
}
res.push_back(make_pair(cur, i));
}
}
sort(res.begin(), res.end());
} void Init() {
fill(d, d + ( << n), );
vector< pair<int, int> > left, right;
int mid = n / ;
MakeSum(vector<int>(a, a + mid), left);
MakeSum(vector<int>(a + mid, a + n), right);
for (int i = ; i < left.size(); ++i) {
int lo = lower_bound(right.begin(), right.end(), make_pair(s - left[i].first, -)) - right.begin();
int hi = upper_bound(right.begin(), right.end(), make_pair(s - left[i].first, << )) - right.begin();
for (int j = lo; j < hi; ++j) {
d[left[i].second | (right[j].second << mid)] = ;
}
}
} int main() {
int T;
scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &s);
for (int i = ; i < n; ++i) {
scanf("%d", a + i);
}
Init();
for (int i = ; i < ( << n); ++i) {
for (int j = (i - ) & i; j > ; j = (j - ) & i) {
d[i] = max(d[i], d[j] + d[i ^ j]);
}
}
printf("%d\n", d[( << n) - ]);
}
return ;
}
Calculation(dfs+状压dp)的更多相关文章
- POJ 1321 棋盘问题(DFS & 状压DP)
用DFS写当然很简单了,8!的复杂度,16MS搞定. 在Discuss里看到有同学用状态压缩DP来写,就学习了一下,果然很精妙呀. 状态转移分两种,当前行不加棋子,和加棋子.dp[i][j]中,i代表 ...
- CODEVS1358【DFS/状压DP】
题目链接[http://codevs.cn/problem/1358/] 题意:这个游戏在一个有10*10个格子的棋盘上进行,初始时棋子位于左上角,终点为右下角,棋盘上每个格子内有一个0到9的数字,每 ...
- Atcoder Beginner Contest152F(DFS+状压DP)
二维状压写成一维状压,省略加上第i条边这一维 #define HAVE_STRUCT_TIMESPEC #include<bits/stdc++.h> using namespace st ...
- 【62测试】【状压dp】【dfs序】【线段树】
第一题: 给出一个长度不超过100只包含'B'和'R'的字符串,将其无限重复下去. 比如,BBRB则会形成 BBRBBBRBBBRB 现在给出一个区间[l,r]询问该区间内有多少个字符'B'(区间下标 ...
- BZOJ-1087 互不侵犯King 状压DP+DFS预处理
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2337 Solved: 1366 [Submit][ ...
- UVaLive 6625 Diagrams & Tableaux (状压DP 或者 DFS暴力)
题意:给一个的格子图,有 n 行单元格,每行有a[i]个格子,要求往格子中填1~m的数字,要求每个数字大于等于左边的数字,大于上边的数字,问有多少种填充方法. 析:感觉像个DP,但是不会啊...就想暴 ...
- HDU 4272 LianLianKan (状压DP+DFS)题解
思路: 用状压DP+DFS遍历查找是否可行.假设一个数为x,那么他最远可以消去的点为x+9,因为x+1~x+4都能被他前面的点消去,所以我们将2进制的范围设为2^10,用0表示已经消去,1表示没有消去 ...
- 【题解】洛谷P3959 [NOIP2017TG] 宝藏(状压DP+DFS)
洛谷P3959:https://www.luogu.org/problemnew/show/P3959 前言 NOIP2017时还很弱(现在也很弱 看出来是DP 但是并不会状压DP 现在看来思路并不复 ...
- bjtu 1846. Infinity的装备[状压dp+dfs/bfs]
https://citel.bjtu.edu.cn/acm/oj/problem/1846 1846. Infinity的装备 时间限制 1000 ms 内存限制 64 MB 题目描述 “测试服终于下 ...
随机推荐
- 自定义一个searchBar
#import "CZSearchBar.h" @implementation CZSearchBar - (instancetype)initWithFrame:(CGRect) ...
- 《招聘一个靠谱的iOS》面试题参考答案(下)
相关文章: <招聘一个靠谱的iOS>面试题参考答案(上) 说明:面试题来源是微博@我就叫Sunny怎么了的这篇博文:<招聘一个靠谱的 iOS>,其中共55题,除第一题为纠错题外 ...
- NET基础课--Linq第三讲
LINQ 1.查询操作符 (1)源起 .net的设计者在IEnumerable<T>等接口基础之上定义了一系列的扩展方法来方便用户操作集合对象,这些扩展方法构成了LINQ的查询操作符 (2 ...
- jQuery中的trigger和triggerhandler区别
$("form :input").blur(function(){ // }).keyup(function(){ $(this).triggerHandler("blu ...
- js判断ie浏览器
function isIE() { //ie? if (!!window.ActiveXObject || "ActiveXObject" in window){ document ...
- jquery文本框验证字符长度和只能输入数字
<input type="text" class="chujia" onkeyup="this.value=this.value.replace ...
- linux字体安装
Google查了一下,果然Windows下的ttf字体与GNOME是兼容的!我立即确定了我的方案——使用Windows下的“微软雅黑”体作为桌面和应用程序的默认字体! 1. 首先获得一套“微软雅黑”字 ...
- 复数类(C++练习一)
写一个复数类,实现基本的运算,目的熟悉封装与数据抽象. 类的定义 #include <iostream> #include <vector> using namespace s ...
- CDZSC_2015寒假新人(2)——数学 D
D - D Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status ...
- CDZSC_2015寒假新人(1)——基础 g
Description Ignatius likes to write words in reverse way. Given a single line of text which is writt ...