Pieces(hdu4628,状态压缩的动态规划)
2013-08-16 21:33
363 查看
http://acm.hdu.edu.cn/showproblem.php?pid=4628
Pieces
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 536 Accepted Submission(s): 317
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
Source
2013 Multi-University Training Contest 3
Recommend
zhuyuanchen520
解析:
题意:给出一个字符串,要求最少需要多少步可以将其删完。其中回文序列可以一次性删掉
思路:
状态压缩的动态规划:
由于数据比较小,所以可以暴力枚举每一种状态然后判断其合法性。
最后用状态转移方程解决即可
562MS 1196K 862 B G++
dp[i]=min(dp[i],dp[i-j]+1);表示i状态下的最小步数,j是i的合法子集;
步骤:
1,枚举每一种状态并记录其合法性
2.在状态转移方程中更新值
仿标称写的
*/
Pieces
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 536 Accepted Submission(s): 317
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
Source
2013 Multi-University Training Contest 3
Recommend
zhuyuanchen520
解析:
题意:给出一个字符串,要求最少需要多少步可以将其删完。其中回文序列可以一次性删掉
思路:
状态压缩的动态规划:
由于数据比较小,所以可以暴力枚举每一种状态然后判断其合法性。
最后用状态转移方程解决即可
562MS 1196K 862 B G++
dp[i]=min(dp[i],dp[i-j]+1);表示i状态下的最小步数,j是i的合法子集;
步骤:
1,枚举每一种状态并记录其合法性
2.在状态转移方程中更新值
仿标称写的
*/
#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; const int maxn=1<<16+1; int inf=10000000; char ch[maxn]; int dp[maxn],can[maxn]; int min(int a,int b){return a<b? a:b;} void work() { int i,j,ok,n,k; int s,t; scanf("%s",ch); n=strlen(ch); for(i=0;i<(1<<n);i++)//枚举每一种状态并且记录其合法性 { char temp[maxn]; k=0; for(j=0;j<n;j++)//举出在i状态下的情形 if(i>>j&1) temp[k++]=ch[j]; ok=1; for(s=0,t=k-1;t>s;t--,s++)//判断该状态是否合法,即是否是回文字 {if(temp[s]!=temp[t]) { ok=0; break; } } can[i]=ok; } dp[0]=0; for(i=1;i<(1<<n);i++) { dp[i]=inf; for(j=i;j>0;(--j)&=i)//枚举j状态下的子集 { if(can[j])//如果该子集合法则列入方程计算 {dp[i]=min(dp[i],dp[i-j]+1); } } } printf("%d\n",dp[(1<<n)-1]); } int main() { int T; scanf("%d",&T); while(T--) { memset(dp,0,sizeof(dp)); work(); } return 0; } /* 1187MS 66084K 1347 B G++ */ #include <iostream> #include <cstdio> #include <algorithm> #include <string> #include <cstring> #include <vector> #include <cassert> using namespace std; typedef long long int64; const int MAX_N = 16, INF = ~0U >> 2; int n; int dp[1 << MAX_N][MAX_N][MAX_N]; //rest,i,j char s[MAX_N + 1]; void work() { scanf("%s", s); n = strlen(s); for (int i = 0; i < n; ++i) { for (int j = i; j < n; ++j) { dp[0][i][j] = 0;//初始化为0 } } for (int rest = 1; rest < (1 << n); ++rest) { for (int i = n - 1; i >= 0; --i) { for (int j = i; j < n; ++j) { //rest,i,j int&ret = dp[rest][i][j] = INF;//rest表示i与j之间的状态 if (i < j) ret = min(dp[rest][i + 1][j], dp[rest][i][j - 1]); if (s[i] == s[j] && (rest >> i & 1) && (rest >> j & 1)) {//当第i个字符状态和第j的字符状态1 int nrest = rest & (~(1 << i)) & (~(1 << j));//将i和j位置0 if (nrest == 0)//若此时状态为全0,即此状态将字符串都删除了 ret = min(ret, dp[nrest][i][j] + 1); else ret = min(ret, dp[nrest][i][j]); } } } for (int i = n - 1; i >= 0; --i) { for (int j = i; j < n; ++j) { dp[rest][i][j] = min(dp[rest][i][j], dp[rest][0][n - 1] + 1); } } } cout << dp[(1 << n) - 1][0][n - 1] << endl; } int main() { int T; cin >> T; while (T--) { work(); } }
相关文章推荐
- Pieces(hdu4628,状态压缩的动态规划)
- [Usaco2005 Open]Disease Manangement 疾病管理|状态压缩动态规划
- 动态规划之状态压缩dp入门
- 状态压缩动态规划 -- 炮兵阵地
- kuangbin求带飞DP1 Doing HomeWork(动态规划+状态压缩)
- POJ3254 Corn Fields 状态压缩动态规划,状压动规
- HDU 3091(动态规划-状态压缩)
- 状态压缩动态规划 -- 棋盘问题 POJ 1321
- 多状态动态规划的压缩
- 状态压缩动态规划 -- 棋盘问题 POJ 1321
- poj 1038 Bugs Integrated, Inc.(动态规划状态压缩)
- hdu 2809 God of War(动态规划之状态压缩)
- 动态规划---状态压缩(即集合上的动态规划)
- 状态压缩动态规划 -- 旅行商问题
- 状态压缩动态规划 -- 旅行商问题
- 基于连通性状态压缩的动态规划--【插头DP】模板超级详细解释
- 动态规划状态压缩题解
- 100道动态规划——24 UVA 1633 Dyslexic Gollum 状态压缩DP 挺好的题 因为窝没想到嘛
- 100道动态规划——25 UVA 1204 Fun Game 状态压缩 圆圈的处理 (100道完成了1/4啦)
- [ACM_动态规划] 轮廓线动态规划——铺放骨牌(状态压缩1)