状压dp的题目列表 (一)
状压dp的典型的例子就是其中某个数值较小。
但是某个数值较小也不一定是状压dp,需要另外区分的一种题目就是用暴力解决的题目,例如UVA818 紫书215
题目列表:
①校长的烦恼 UVA10817 紫书286
②20个问题 UVA 1252 紫书287
③
④
⑤
⑥
⑦
⑧
⑨
⑩
一:校长的烦恼 UVA10817 紫书286
题目大意:n个求职者,m个教师,需要讲授s门课程,每门课要有至少2个人讲授。教师是必须雇佣的,求职者看情况。给出教师和求职者的工资和能教授的科目。问怎么雇佣才能支付最少的工资?
思路:定义dp[i][s1][s2]表示,s1表示每门课只有一个人教,s2表示每门课有两名以上的人教的。i表示前i个人的雇佣情况,这样进行dp就好了。 具体看紫书吧,很详细
//看看会不会爆int! 或者绝对值问题。
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define ALL(a) a.begin(), a.end()
const int maxs = ( << ) + ;
const int inf = 0x3f3f3f3f;
const int maxn = + ;
int s, m, n;
int dp[maxn][maxs][maxs], money[maxn], st[maxn]; int dfs(int i, int s1, int s2){
if (i == m + n){
return s2 == (<<s)- ? : inf;
}
int &ans = dp[i][s1][s2];
if (ans >= ) return ans;
ans = inf;
if (i >= m) ans = dfs(i + , s1, s2);
int t = st[i];
int tmp = s1 & t;
ans = min(ans, dfs(i + , s1 | t, s2 | tmp) + money[i]);
return ans;
} int main(){
string line;
int x;
while (getline(cin, line)){
stringstream ss(line);
ss >> s >> m >> n;
if (s == ) break;
for (int i = ; i < m + n; i++){
getline(cin, line);
stringstream ss(line);
ss >> money[i];
st[i] = ;
while (ss >> x) st[i] |= ( << x-);
}
memset(dp, -, sizeof(dp));
dfs(, , );
printf("%d\n", dp[][][]);
}
return ;
}
关键:学会划分情况
二:20个问题 UVA1252 紫书267
题目大意:有n个长度为m的二进制串,每个都是不同的。为了把所有字符串区分开,你可以询问,每次可以问某位上是0还是1。问最少提问次数,可以把所有字符串区分开来。
思路:dp是要枚举已知的所需要的所有状态的,那么我们如何来枚举目前的状态呢。首先我们定义dp[s][a],s表示目前已经询问了的集合,a表示目前s的子集当中的特征集。因此就表示,已经询问了特征集s,确认了所具备的特征集a,还需要询问的最小次数是多少。
因此我们的决策时dp[s][a] = max(dp[s + {k}][a + {k}], dp[s + {k}][a]) + 1;
然后通过dfs来解决就行了。虽然也可以用递推来实现。
//看看会不会爆int! 或者绝对值问题。
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define ALL(a) a.begin(), a.end()
///当所有的物品所具备的特征只剩下1的时候,说明其他全都访问过
const int maxn = + ;
const int maxm = ( << ) + ;
int cnt[maxm][maxm], dp[maxm][maxm];
int n, m;
char ch[maxn]; void init(){
memset(cnt, , sizeof(cnt));
for (int i = ; i < n; i++){
scanf("%s", ch);
int t = ;
for (int j = ; j < m; j++)
if (ch[j] == '') t |= ( << j);
for (int j = ; j < ( << m); j++){///给所有的都做上标记,一个的时候,两个的时候都有
cnt[j][j & t]++;
}
}
} int dfs(int s, int a){
if (cnt[s][a] <= ) return ;
if (cnt[s][a] == ) return ; int &ans = dp[s][a];
if (dp[s][a] >= ) return ans;
ans = m;
for (int i = ; i < m; i++){
if (s & ( << i)) continue;
int s2 = s | ( << i), a2 = a | ( << i);
if (cnt[s2][a] >= && cnt[s2][a2] >= ){
int tmp = max(dfs(s2, a), dfs(s2, a2)) + ;
ans = min(tmp, ans);
}
}
return ans;
} int main(){
while (scanf("%d%d", &m, &n) == && n+m > ){
memset(dp, -, sizeof(dp));
init();
printf("%d\n", dfs(, ));
}
return ;
}
感觉这道题让现在我这样的水平的人来做肯定做不来,要仔细看看
三:
四:
五:
六:
七:
八:
九:
十:
状压dp的题目列表 (一)的更多相关文章
- 状压dp(状态压缩&&dp结合)学习笔记(持续更新)
嗯,作为一只蒟蒻,今天再次学习了状压dp(学习借鉴的博客) 但是,依旧懵逼·································· 这篇学习笔记是我个人对于状压dp的理解,如果有什么不对的 ...
- POJ1185 状压dp(二进制//三进制)解法
很显然这是一道状压dp的题目 由于每个最优子结构和前两行有关,一个显而易见的想法是用三维dp[i][j][k]用来记录在第i行下为j状态,i - 1行为k状态时的最大值,然而dp[100][1 < ...
- ZOJ 3777 - Problem Arrangement - [状压DP][第11届浙江省赛B题]
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3777 Time Limit: 2 Seconds Me ...
- M - Little Pony and Harmony Chest 状压dp
M - Little Pony and Harmony Chest 怎么感觉自己越来越傻了,都知道状态的定义了还没有推出转移方程. 首先这个a的范围是0~30 这里可以推出 b数组的范围 0~60 ...
- 「算法笔记」状压 DP
一.关于状压 dp 为了规避不确定性,我们将需要枚举的东西放入状态.当不确定性太多的时候,我们就需要将它们压进较少的维数内. 常见的状态: 天生二进制(开关.选与不选.是否出现--) 爆搜出状态,给它 ...
- 状压DP入门详解+题目推荐
在动态规划的题型中,一般叫什么DP就是怎么DP,状压DP也不例外 所谓状态压缩,一般是通过用01串表示状态,充分利用二进制数的特性,简化计算难度.举个例子,在棋盘上摆放棋子的题目中,我们可以用1表示当 ...
- 状压DP详解+题目
介绍 状压dp其实就是将状态压缩成2进制来保存 其特征就是看起来有点像搜索,每个格子的状态只有1或0 ,是另一类非常典型的动态规划 举个例子:有一个大小为n*n的农田,我们可以在任意处种田,现在来描述 ...
- nefu1109 游戏争霸赛(状压dp)
题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...
- poj3311 TSP经典状压dp(Traveling Saleman Problem)
题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...
随机推荐
- php长整型完整输出
今天调用webservice时返回一个字段是int64 长整型 原始的数值应该是 190000002101056096 而php返回时转成 1.9000000210106E+17 当传入另一个接口就报 ...
- SharePoint2013修复报错
今天项目组的Sharepoint2013不小心被卸载了,本想着直接修复,谁知道在修复的时候一直报错,说找不到什么文件.报的就是类似于这样的错误: Product: ######### -- ...
- xadmin站点管理面样样式控制
xadmin可以使用的页面样式控制基本与Django原生的admin一直. list_display 控制列表展示的字段 search_fields 控制可以通过搜索框搜索的字段名称,xadmin使用 ...
- 为什么mysqld启动报错
在一台ubuntu测试机器上启动一个mysql实例,本来应该是一件很简单的事情, 启动的时候却报错了: mysqld_safe --defaults-file=/etc/mysql/my3307. ...
- C指针分析详解
局部变量和全局变量初始化区别: 局部变量,在未初始化情况下,初值为随机值.C规范对该初值并没有做规定,具体实现由编译器决定.如VC/VS等编译器,会将初始值值为0xCCCCCCCC, 而GCC等编译器 ...
- Android之 GPS学习笔记
========================================GPS:全球定位系统 GPS由三部分组成:GPS卫星组成的空间部分,若干地面组成的控制站,用户手中的接收机.Androi ...
- php中数据类型的强制转换
1.在PHP开发种在很多的地方要涉及到数据类型的转换,尤其是涉及到金额的数据类型,一定要转换成float类型,否则在入库的时候可能会因为数据类型的不同覆盖掉之前的金额.(字符串和float类型相加) ...
- UVA 11883 Repairing a Road(最短路径+暴力枚举)
You live in a small town with R bidirectional roads connecting C crossings and you want to go from c ...
- [转]Hexo博客添加访问统计 - 记录
引入不蒜子 <script async src="//dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js"> ...
- 详解python 局部变量与全局变量
本文将详细分析python的全局变量与局部变量,学过php的人都知道,php里面的全局变量是无法在function里面去使用的,只有超全局变量才可以,那么python会怎么处理全局变量与局部变量呢?下 ...