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. office文件密码破解方法及软件

    今天会用到3个软件 1.Office Password Remover 说明:这个软件可以很快破解.doc   .xls的密码 使用方法:参考百度经验里面的文章http://jingyan.baidu ...

  2. Esper系列(三)Context和Group by

    Context 把不同的事件按照框的规则框起来(规则框在partition by中定义),并且有可能有多个框,而框与框之间不会互相影响. 功能: 组合事件查询并进行分组,类型:Hash Context ...

  3. POJ1423 - Big Number(Stirling公式)

    题目大意 求N!有多少位 题解 用公式直接秒杀... 代码: #include<iostream> #include<cmath> using namespace std; # ...

  4. MyBatis Oracle批量更新

    <update id="updateProductSerialNo" parameterType="java.util.List"> <for ...

  5. PHP函数补完:var_export()

    var_export() 函数返回关于传递给该函数的变量的结构信息,它和 var_dump() 类似,不同的是其返回的表示是合法的 PHP 代码.var_export必须返回合法的php代码, 也就是 ...

  6. maven依赖规则

    1.就近原则,传递依赖 A-B-C -> A-C 2.先声明原则 A-B-C D-E-C 依赖的规则阻止了jar包冲突

  7. Mysql相关问答

    问:我们团队中的一人想要使用 bigint 字段类型来代替 25-30 长度的 varchar 类型来存储 CRC64 数据,然后将索引也改成 bigint 的索引,这会节省索引的空间.请问这否是合理 ...

  8. java web知识点总结

    创建与销毁 ServletContext HttpRequest HttpSession 1.ServletContext 创建:启动服务器时就创建,服务为每个web应用创建该项目的ServleCon ...

  9. AndroidのUI设计研究(一)——自定义ProgressBar

    最近迷上进度条,使用进度条可以增强用户体验,让用户心里有个底,再无奈的等待中体会loading的乐趣. 记得以前优乐美的官网,进入主页加载资源,显示给用户看的就是,炫彩背景下,一个杯子里的奶茶随着加载 ...

  10. android 98 MediaPlayer+SurfaceView播放视频

    package com.itheima.videoplayer; import java.io.IOException; import android.media.MediaPlayer; impor ...