hdu4628之状态压缩dp
2014-03-21 22:53
351 查看
Pieces
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1518 Accepted Submission(s): 788
Problem Description
You heart broke into pieces.My string broke into pieces.But you will recover one day,and my string will never go back.
Given a string s.We can erase a subsequence of it if this subsequence is palindrome in one step. We should take as few steps as possible to erase the whole sequence.How many steps do we need?
For example, we can erase abcba from axbyczbea and get xyze in one step.
Input
The first line contains integer T,denote the number of the test cases. Then T lines follows,each line contains the string s (1<= length of s <= 16).
T<=10.
Output
For each test cases,print the answer in a line.
Sample Input
2 aa abb
Sample Output
1 2
分析:对于字符串len个位置,假设在某个字串含有原串k位置则k位置表示为1,否则表示为0,则枚举所有字串共有2^len种
对于每种字串状态i,枚举包含状态i的状态j(既i中有1的位置j也有),然后判断状态j表示的字串消除的串i^j是否是回文串,是得话就可以从状态j到达状态i
对于如何枚举包含状态i的状态j:
for(int j=i;j<2^len;j=(j+1)|i);
比如:
i:1 1 0 1 0
j;1 1 0 1 0
则j+1:1 1 0 1然后(j+1)|i就将i中第一个为0的位置变为1
然后继续(j+1)|i其实就是在原前面已变位置的前提下,如果该位置前面还有0的就变成1,否则找下一个位置变为1
当然也可以枚举状态i的子状态:
for(int j=i;j>0;j=(j-1)&i);
枚举包含状态i的状态:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <queue> #include <algorithm> #include <map> #include <iomanip> #define INF 99999999 typedef long long LL; using namespace std; const int MAX=(1<<16)+10; int len,bit; int dp[MAX]; char s[20]; bool mark[MAX]; bool check(int x){ if(x == 0)return true; int i=0,j=len-1; while(i<j){ while(!(x&(1<<i)))++i; while(!(x&(1<<j)))--j; if(s[i] != s[j])return false; ++i,--j; } return true; } int main(){ int t; scanf("%d",&t); while(t--){ scanf("%s",s); len=strlen(s); bit=1<<len; dp[bit-1]=0; for(int i=0;i<bit;++i)mark[i]=check(i); for(int i=bit-2;i>=0;--i){ dp[i]=INF; for(int j = i;j<bit;j=(j+1)|i){ if(!mark[i^j])continue; if(dp[i]>dp[j]+1)dp[i]=dp[j]+1; } } printf("%d\n",dp[0]); } return 0; }枚举状态i的子状态:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <queue> #include <algorithm> #include <map> #include <iomanip> #define INF 99999999 typedef long long LL; using namespace std; const int MAX=(1<<16)+10; int len,bit; int dp[MAX]; char s[20]; bool mark[MAX]; bool check(int x){ if(x == 0)return true; int i=0,j=len-1; while(i<j){ while(!(x&(1<<i)))++i; while(!(x&(1<<j)))--j; if(s[i] != s[j])return false; ++i,--j; } return true; } int main(){ int t; scanf("%d",&t); while(t--){ scanf("%s",s); len=strlen(s); bit=1<<len; for(int i=0;i<bit;++i)mark[i]=check(i); for(int i=0;i<bit;++i)dp[i]=INF; dp[bit-1]=0; for(int i=bit-1;i>=0;--i){ for(int j = i;j>0;j=((j-1)&i)){ if(!mark[i^j])continue; if(dp[j]>dp[i]+1)dp[j]=dp[i]+1; } if(mark[i])if(dp[0]>dp[i]+1)dp[0]=dp[i]+1; } printf("%d\n",dp[0]); } return 0; }
相关文章推荐
- UVa1554 - Binary Search
- 关于加强保护网站安全的想法--引于IDF博文
- HDU 1676 Full Tank? 限制最短路(difficult)
- linux 简单的mysql备份和导入,以及文件的备份和导入
- 使用 Video4Linux 采集USB摄像头的图像,并保存到一张 jpg图像文件中的程序
- 仿jdk的LinkedList代码实现
- Facebook HHVM 和 Hack 手册----1.什么是Hack?
- linux 简单的mysql备份和导入,以及文件的备份和导入
- 14.6: 脚本化状态栏
- Linux服务器的初步配置流程
- SQLServer创建约束
- git 常用命令总结
- 代码质量
- Cocos2D-x游戏开发之九:屏幕触摸一:基本屏幕操作响应
- 全备份、增量备份、差异备份和永久增量备份
- ADS1.2 DEBUG调试时提示:erro starting external process,Process error code 87(0x57)
- 14.5: 简单的对话框
- this
- 深入java虚拟机 - 垃圾收集 - 火车算法
- Linux下SVN的备份与恢复