Pieces(hdu4628,状态压缩的动态规划)
来源:互联网 发布:龙城飞将 知乎 编辑:程序博客网 时间:2024/06/07 06:05
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.在状态转移方程中更新值
仿标称写的
*/
#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;}/*1187MS66084K1347 BG++*/#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,jchar 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,jint&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的字符状态1int nrest = rest & (~(1 << i)) & (~(1 << j));//将i和j位置0if (nrest == 0)//若此时状态为全0,即此状态将字符串都删除了ret = min(ret, dp[nrest][i][j] + 1);elseret = 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,状态压缩的动态规划)
- Pieces(hdu4628,状态压缩的动态规划)
- HOJ-2662Pieces Assignment(状态压缩,动态规划)
- hdu4628状态压缩DP
- HDU4628+状态压缩DP
- hdu4628(状态压缩DP)
- hdu4628(状态压缩dp)
- hdu4628 Pieces
- 状态压缩的动态规划
- hdu4628之状态压缩dp
- hdu4628 状态压缩搜索or状态dp
- 状态压缩动态规划
- 状态压缩动态规划
- 状态压缩动态规划
- 状态压缩动态规划
- 状态压缩动态规划
- 动态规划!状态压缩
- 状态压缩动态规划
- No Pain No Game(hdu4630,树状数组+数学)
- iOS之KVC和KVO
- 逆向输出一个字符串
- 树状数组
- djanglebook
- Pieces(hdu4628,状态压缩的动态规划)
- Android-GPS定位
- SRM 588 D2 L2:GUMIAndSongsDiv2,冷静思考,好的算法简洁明了
- 不使用额外空间实现两个变量(int 型)的交换
- 泰山挑夫【三】解题报告
- 循环右移字符串简易探讨
- Sad Love Story(hdu4631,模拟+set容器)
- 创建一个和已知表相同的表
- 大数据相乘