hdu - 4628 - Pieces(状态压缩dp)
来源:互联网 发布:软件著作权软件说明书 编辑:程序博客网 时间:2024/06/07 06:14
题意:给出一个长度不超过16的字符串s,问最少删除多少次其中的回文串能把整个s删得干干净净(回文串可跨字母组成),共T组测试数据(T <= 10)。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4628
——>>集合上的动态规划。。。和点集配对很像,这里我先求出所有的回文串,然后dp。
设d[S]表示将集合S中的字母删除需要多少步,结果就是d[(1<<n)-1];
枚举所有的S,枚举所有S的子集sub;
状态转移方程:d[S] = min(d[S], d[S^sub)] + 1](如果sub是回文串~这样才算能减一步呀);
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn = 16 + 1;const int INF = 1000000000;char s[maxn];bool ispal[1<<maxn];int d[1<<maxn], n;void getPal() //求出所有的回文串{ int S, i, j; for(S = 0; S < (1<<n); S++){ bool ok = 1; int m = 0, buf[maxn]; for(i = 0; i < n; i++) if((1<<i) & S){ buf[m++] = s[i]; } for(i = 0, j = m-1; i < j; i++, j--){ if(buf[i] != buf[j]){ ok = 0; break; } } ispal[S] = ok; }}void dp(){ int S, sub; d[0] = 0; for(S = 1; S < (1<<n); S++){ d[S] = INF; for(sub = S; sub > 0; sub = (sub-1) & S){ if(ispal[sub]) d[S] = min(d[S], d[S^sub] + 1); } }}int main(){ int T; scanf("%d", &T); while(T--){ scanf("%s", s); n = strlen(s); getPal(); dp(); printf("%d\n", d[(1<<n)-1]); } return 0;}
- hdu - 4628 - Pieces(状态压缩dp)
- HDU 4628 Pieces(状态压缩dp)
- hdu 4628 Pieces(状态压缩DP)
- hdu 4628 Pieces (状态压缩dp)
- hdu 4628 Pieces (状态压缩dp)
- hdu 4628 Pieces 状态压缩DP
- HDU 4628 Pieces(状态压缩DP)
- hdu 4628 Pieces (状态压缩+二进制枚举+dp)
- hdu 4628 - Pieces(压缩dp)
- hdu 4628 Pieces(状态压缩+记忆化搜索)
- Pieces (状态dp)
- HOJ 2662 Pieces Assignment(状态压缩DP)
- HOJ 2662 Pieces Assignment(状态压缩DP)
- hdu 4628 Pieces(状压dp)
- hdu 4628(状态压缩dp)
- hdu 4628 Pieces 集合DP
- [kmp+dp] hdu 4628 Pieces
- [状压dp] hdu 4628 Pieces
- FC协议详解
- 提高网站访问速度的34条军规(20-25)
- class 类
- 提高网站访问速度的34条军规(26-30)
- 提高网站访问速度的34条军规(31-34)
- hdu - 4628 - Pieces(状态压缩dp)
- SVN commit:remains in tree-conflict错误的解决办法
- 【Hadoop】Simple Authentication
- mysql数据类型
- 一起学WF3.5【4】
- 正则表达式
- Cocos2d-x win7 + vs2010 配置图文详解
- android listview 更新一行
- 13暑假集训#9 总结