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是回文串~这样才算能减一步呀);

 
代码如下:
 # include<cstdio>
# include<cstring>
# include<algorithm> using namespace std; const int maxn = + ;
const int INF = 0xffffff;
char s[maxn];
bool ispal[<<maxn]; //ispal[i]表示状态i是否是回文,2进制时1表示选择这个字符,0表示不选择这个字符
int d[<<maxn]; //d[S]表示将集合S中的字母删除需要多少步,结果就是d[(1<<n)-1]
int n; void getPal() //求出所有的回文串
{
int S, i, j;
for(S = ; S < (<<n); S++){ //状态S是否回文
bool ok = ;
int m = , buf[maxn]; //临时存储提取出来的字符
for(i = ; i < n; i++) if((<<i) & S){ //提取对应字符
buf[m++] = s[i];
}
for(i = , j = m-; i < j; i++, j--){ //判断回文
if(buf[i] != buf[j]){
ok = ;
break;
}
}
ispal[S] = ok;
}
} void dp(){
int S, sub;
d[] = ;
for(S = ; S < (<<n); S++){
d[S] = INF;
for(sub = S; sub > ; sub = (sub-) & S){ //sub = (sub-1) & S)保证是集合S中的字母
if(ispal[sub]) d[S] = min(d[S], d[S^sub] + ); //S^sub就是剩下的字符
}
}
} int main()
{
int T;
scanf("%d", &T);
while(T--){
scanf("%s", s);
n = strlen(s);
getPal();
dp();
printf("%d\n", d[(<<n)-]);
}
return ;
}

附贴标程:

 #include <iostream>
#include <cstdio>
#include <cstring>
using namespace std; int min(int a,int b){
return a<b ?a :b;
} const int MAX_N = , INF = 0xffffff;
int n;
int dp[ << MAX_N][MAX_N][MAX_N]; //rest,i,j
char s[MAX_N + ];
void work() {
int i,j,k;
scanf("%s", s);
n = strlen(s); for (i = ; i < n; i++) {
for (j = i; j < n; j++) {
dp[][i][j] = ;
}
} for (int rest = ; rest < ( << n); rest++) {
for (i = n - ; i >= ; i--) {
for (j = i; j < n; j++) {
//rest,i,j
int &ret = dp[rest][i][j] = INF;
if (i < j)
ret = min(dp[rest][i + ][j], dp[rest][i][j - ]);
if (s[i] == s[j] && ((rest >> i) & ) && ((rest >> j) & )) {
int nrest = rest & (~( << i)) & (~( << j));
if (nrest == )
ret = min(ret, dp[nrest][i][j] + );
else
ret = min(ret, dp[nrest][i][j]);
}
}
}
for (i = n - ; i >= ; i--) {
for (int j = i; j < n; j++) {
dp[rest][i][j] = min(dp[rest][i][j], dp[rest][][n - ] + );
}
}
} cout << dp[( << n) - ][][n - ] << endl;
} int main() {
int T;
cin >> T;
while (T--) {
work();
}
}

HDU 4628 Pieces(DP + 状态压缩)的更多相关文章

  1. HDU 4628 Pieces(状态压缩+记忆化搜索)

    http://acm.hdu.edu.cn/showproblem.php?pid=4628 题意:给个字符窜,每步都可以删除一个字符窜,问最少用多少步可以删除一个字符窜分析:状态压缩+记忆化搜索  ...

  2. hdu 4628 Pieces(状态压缩+记忆化搜索)

    Pieces Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total S ...

  3. hdu 4352 数位dp + 状态压缩

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

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

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

  5. HDU 1074 Doing Homework (dp+状态压缩)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目大意:学生要完成各科作业, 给出各科老师给出交作业的期限和学生完成该科所需时间, 如果逾期一 ...

  6. HDU 4336 Card Collector (期望DP+状态压缩 或者 状态压缩+容斥)

    题意:有N(1<=N<=20)张卡片,每包中含有这些卡片的概率,每包至多一张卡片,可能没有卡片.求需要买多少包才能拿到所以的N张卡片,求次数的期望. 析:期望DP,是很容易看出来的,然后由 ...

  7. hdu_4352_XHXJ's LIS(数位DP+状态压缩)

    题目连接:hdu_4352_XHXJ's LIS 题意:这题花大篇篇幅来介绍电子科大的一个传奇学姐,最后几句话才是题意,这题意思就是给你一个LL范围内的区间,问你在这个区间内最长递增子序列长度恰为K的 ...

  8. 【bzoj1076】[SCOI2008]奖励关 期望dp+状态压缩dp

    题目描述 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再 ...

  9. hdu4336 Card Collector(概率DP,状态压缩)

    In your childhood, do you crazy for collecting the beautiful cards in the snacks? They said that, fo ...

  10. dp状态压缩

    dp状态压缩 动态规划本来就很抽象,状态的设定和状态的转移都不好把握,而状态压缩的动态规划解决的就是那种状态很多,不容易用一般的方法表示的动态规划问题,这个就更加的难于把握了.难点在于以下几个方面:状 ...

随机推荐

  1. hadoop入门必备基础知识

    1.对Linux 系统的要求        会基本的命令:        (1)知道root用户        (2)ls命令会查看文件夹内容        (3)cd命令等2.Java 的要求    ...

  2. Apple LLVM 6.0 Warning: profile data may be out of date

    I have no clue what this meant, so I googled the problem. I only ended up with some search results s ...

  3. Linux的read命令

    对于写bash脚本的朋友,read命令是不可或缺的,需要实践一下就可以了解read命令的大致用途: 编写一个脚本: #!/bin/bash # hao32 test read echo -e &quo ...

  4. python 一些重要的内建异常类

  5. Windows7 64位机上Emgu CV2.4.2安装与配置

    Windows7 64位机上Emgu CV2.4.2安装与配置         分类:             Emgu CV              2012-11-28 17:22     92 ...

  6. Filter案例

    1.有选择的被访问 描述:首先若用户没有在页面提交注册(直接访问list.jsp),就只能被允许访问a.jsp.其他页面均不被允许访问 在login.jsp提交信息之后,可以在b.jsp访问, 代码如 ...

  7. 《机器学习实战》——K近邻算法

    三要素:距离度量.k值选择.分类决策 原理: (1) 输入点A,输入已知分类的数据集data (2) 求A与数据集中每个点的距离,归一化,并排序,选择距离最近的前K个点 (3) K个点进行投票,票数最 ...

  8. PHP工具下载地址

    Zend Debugger下载地址:http://www.zend.com/en/products/studio/downloads 需要先注册一下,然后才能进行下载.

  9. navicate恢复数据

    恢复psc文件,出现记录数为0 不要使用事务,选用遇到错误继续

  10. ApkTool动态打包

    引言: APK在推广的时候可能会须要动态打包APK.比方公布到不同渠道的时候,须要在manifest文件里改动渠道信息.或者app在推广的时候.须要在apk包里面加上推广人信息等. 环境变量: 1.J ...