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 题目描述 “测试服终于下 ...
随机推荐
- C# 二叉堆
二叉堆数据结构讲解: http://www.cnblogs.com/yc_sunniwell/archive/2010/06/28/1766751.html C#代码实现 using System ...
- pyqt最小化学习
# -*- coding: cp936 -*- #!/usr/bin/env python # -*- coding:utf-8 -*- from PyQt4 import QtCore, QtGui ...
- MooseFS源代码分析(三)
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/ ...
- Why Hadoop2
自从Hadoop2出现之后,其迅速代替了Hadoop1的地位,并丰富了Hadoop的应用场景.假设如今有公司使用Hadoop的话,往往直接採用Hadoop2了. Hadoop2能被如此广泛的使用,肯定 ...
- 在OC和Swift中使用IBDesignable/IBInspectable
iOS8新特性IBDesignable/IBInspectable,可以直接在XIB或者Storyboard中直接,设置UI类的属性.例 如:UIView.layer.borderWidth.bord ...
- windows 和linux 同步api对比
初始化临界区 (win) InitializeCriticalSection(RTL_CRITICAL_SECTION &rtl_critial_section) (linux) pthrea ...
- gdal_merge.py
1 gdal_merge.py: 合并(Merge)/镶嵌(Mosaic)工具.要求图像必须是相同坐标系统.具有相同的波段数:可以不同分辨率,可以有重叠区域(后加入图像覆盖先加入的图像). 注意:只能 ...
- PHP学习笔记三十四【记录日志】
<?php function my_error2($errno,$errmes) { echo "错误号:".$errno; //默认时区是格林威治相差八个时区 //设置 1 ...
- iOS 开发者证书总结
iOS 证书分两种类型. 第一种为$99美元的,这种账号有个人和公司的区别,公司账号能创建多个子账号,但个人的不能.这种账号可以用来上传app store 第二种为¥299美元的,这种账号只能用于企业 ...
- IOS 中关于自定义Cell 上的按钮 开关等点击事件的实现方法(代理)
1.在自定义的Cell .h文件中写出代理,写出代理方法. @protocol selectButtonDelegate <NSObject> -(void)selectModelID:( ...