Pieces

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4628

题目大意:给定一个字符串s,如果子序列中有回文,可以一步删除掉它,求把整个序列删除所需要的最少步数。比如: axbyczbea 可以一次删除掉 abcba 得到 xyze

Sample Input
2
aa
abb

Sample Output
1
2
分析:这道题目刚出来时居然有超过一半的人AC,是我太弱了吗?
  到底不会,先贴出标程,再慢慢消化好了
  

  集合上的动态规划。。。和点集配对很像,这里我先求出所有的回文串,然后dp。

  设d[S]表示将集合S中的字母删除需要多少步,结果就是d[(1<<n)-1];

  枚举所有的S,枚举所有S的子集sub;

  状态转移方程:d[S] = min(d[S], d[S^sub)] + 1](如果sub是回文串~这样才算能减一步呀);

 
代码如下:
 1 # include<cstdio>
 2 # include<cstring>
 3 # include<algorithm>
 4
 5 using namespace std;
 6
 7 const int maxn = 16 + 1;
 8 const int INF = 0xffffff;
 9 char s[maxn];
10 bool ispal[1<<maxn];    //ispal[i]表示状态i是否是回文,2进制时1表示选择这个字符,0表示不选择这个字符
11 int d[1<<maxn];        //d[S]表示将集合S中的字母删除需要多少步,结果就是d[(1<<n)-1]
12 int n;
13
14 void getPal()       //求出所有的回文串
15 {
16     int S, i, j;
17     for(S = 0; S < (1<<n); S++){    //状态S是否回文
18         bool ok = 1;
19         int m = 0, buf[maxn];    //临时存储提取出来的字符
20         for(i = 0; i < n; i++) if((1<<i) & S){    //提取对应字符
21             buf[m++] = s[i];
22         }
23         for(i = 0, j = m-1; i < j; i++, j--){ //判断回文
24             if(buf[i] != buf[j]){
25                 ok = 0;
26                 break;
27             }
28         }
29         ispal[S] = ok;
30     }
31 }
32
33 void dp(){
34     int S, sub;
35     d[0] = 0;
36     for(S = 1; S < (1<<n); S++){
37         d[S] = INF;
38         for(sub = S; sub > 0; sub = (sub-1) & S){    //sub = (sub-1) & S)保证是集合S中的字母
39             if(ispal[sub]) d[S] = min(d[S], d[S^sub] + 1);    //S^sub就是剩下的字符
40         }
41     }
42 }
43
44 int main()
45 {
46     int T;
47     scanf("%d", &T);
48     while(T--){
49         scanf("%s", s);
50         n = strlen(s);
51         getPal();
52         dp();
53         printf("%d\n", d[(1<<n)-1]);
54     }
55     return 0;
56 }

附贴标程:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5
 6 int min(int a,int b){
 7     return a<b ?a :b;
 8 }
 9
10 const int MAX_N = 16, INF = 0xffffff;
11 int n;
12 int dp[1 << MAX_N][MAX_N][MAX_N]; //rest,i,j
13 char s[MAX_N + 1];
14 void work() {
15     int i,j,k;
16     scanf("%s", s);
17     n = strlen(s);
18
19     for (i = 0; i < n; i++) {
20         for (j = i; j < n; j++) {
21             dp[0][i][j] = 0;
22         }
23     }
24
25     for (int rest = 1; rest < (1 << n); rest++) {
26         for (i = n - 1; i >= 0; i--) {
27             for (j = i; j < n; j++) {
28                 //rest,i,j
29                 int &ret = dp[rest][i][j] = INF;
30                 if (i < j)
31                     ret = min(dp[rest][i + 1][j], dp[rest][i][j - 1]);
32                 if (s[i] == s[j] && ((rest >> i) & 1) && ((rest >> j) & 1)) {
33                     int nrest = rest & (~(1 << i)) & (~(1 << j));
34                     if (nrest == 0)
35                         ret = min(ret, dp[nrest][i][j] + 1);
36                     else
37                         ret = min(ret, dp[nrest][i][j]);
38                 }
39             }
40         }
41         for (i = n - 1; i >= 0; i--) {
42             for (int j = i; j < n; j++) {
43                 dp[rest][i][j] = min(dp[rest][i][j], dp[rest][0][n - 1] + 1);
44             }
45         }
46     }
47
48     cout << dp[(1 << n) - 1][0][n - 1] << endl;
49 }
50
51 int main() {
52     int T;
53     cin >> T;
54     while (T--) {
55         work();
56     }
57 }

HDU 4628 Pieces(DP + 状态压缩)相关推荐

  1. [HDU 4842]--过河(dp+状态压缩)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4842 过河 Time Limit: 3000/1000 MS (Java/Others)    Mem ...

  2. CCF201409-5 拼图(100分)【插头DP+状态压缩】

    试题编号: 201409-5 试题名称: 拼图 时间限制: 3.0s 内存限制: 256.0MB 问题描述: 问题描述 给出一个n×m的方格图,现在要用如下L型的积木拼到这个图中,使得方格图正好被拼满 ...

  3. DP——状态压缩dp

    状态压缩DP 蒙德里安的梦想 分析题目,当我们先摆横着放的方块,再摆放竖着放的方块,当横着放的小方块摆放完后,竖着放的方块也就确定了,因此总方案数应该等于只放横着的小方块的合法方案数.我们考虑每一列可 ...

  4. hdu 3681(bfs+dfs+状态压缩)

    解题思路:这道题属于图上来回走的问题,可以把重复走的过程弱化,即只强调从u->v的结果,中间经过的节点都不考虑.这道题里面'G','F','Y'是重要的节点,其余的点我们是可以忽略的,也就是说, ...

  5. HDU 4407 Sum(容斥原理+状态压缩)

    题目链接 容斥原理不会,map不会,状态压缩不会.做毛线... 题目大意:给出1-n,n个数,有两个操作1是询问x-y区间上与p互质的数的和是多少,2是改变x位置上的数为c. 自己确实办不了,map这 ...

  6. 【HDU 4352】 XHXJ's LIS (数位DP+状态压缩+LIS)

    XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  7. HDU 4997 Biconnected (状态压缩DP)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4997 题意:一个n个点的完全图中去掉一些边.求这个图有多少个子图是边双联通的.(就是去掉任意一条边之后 ...

  8. 洛谷1052——过河(DP+状态压缩)

    题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数 ...

  9. HDU 4332 Constructing Chimney [状态压缩+矩阵]

    烟囱是一个3*3的中空构造,给定烟囱的高度,问用1*1*2的砖头搭成这个烟囱有多少种方法. 首先用一个8位二进制数表示某一层的状态.枚举上下两层的状态,判断这两个状态是否可以相邻,上一层必须将下层填满 ...

最新文章

  1. JSP内置对象基础知识小结
  2. 性能测试,负载测试,压力测试以及容量测试的联系与区别--网搜及总结
  3. (03) spring Boot 的配置
  4. 使用Spring Security 资源服务器来保护Spring Cloud 微服务
  5. yolov5训练自己的数据
  6. 【Linux环境】修改登录提示语(工作小情趣)+ Banner在线生成工具链接分享(腾讯云 CentOS release 7.5.1804)
  7. c语言中指,浅析C语言中指与数组.doc
  8. 1147 Heaps
  9. java按条件查询结果为空_mybatis中查询结果为空时不同返回类型对应返回值问题...
  10. UVA10579 Fibonacci Numbers【大数】
  11. 简单介绍一下vue2.0
  12. eclipse工具按键翻译
  13. Ceres Solver (ubuntu 安装)
  14. JeecgBoot全套开发环境搭建
  15. 粗糙集理解之一:基本概念
  16. 7 php 内存泄漏_PHP内存泄漏分析定位
  17. Android 10 原生支持 5G!
  18. h5 实现扫码二维码及条形码(js多种实现方式)
  19. D. Cloud of Hashtags(逆向贪心)
  20. 2022-05-25 网工进阶(七)OSPF-影响邻居关系建立的因素、路由撤销、路由汇总、路由过滤、Silent-Interface、报文认证

热门文章

  1. angular2 学习二 最简单的模板
  2. linux screen 命令详解
  3. dede日期时间标签调用大全
  4. 【转】使用genstring和NSLocalizedString实现App文本的本地化
  5. ROS教程(3)---静态NAT配置及应用 (
  6. SQL Sever索引
  7. ASP.NET Web 页面生命中的一天
  8. wps office oa控件 痕迹_WPS大更新,Office的付费功能免费用,我不会是最后一个知道的吧?...
  9. 更新版PowerBI发布了-- Power BI Report Server Update – March 2018
  10. oracle简单命令