比较水的动态规划
dp[i][j] 将原串 i ~ j 之内的字符转化为回文字符所需要的最小操作次数
其中删除操作和添加操作本质上是一样的。
三个状态转移方程:
dp[i][j] = min(dp[i][j] ,dp[i + 1][j]);
dp[i][j] = min(dp[i][j] ,dp[i + 1][j - 1]);
dp[i][j] = min(dp[i][j] ,dp[i][j - 1]);
如果 i = j dp[i][j] = 0;
| 14145138 | 10651 | Pebble Solitaire | Accepted | C++ | 0.009 | 2014-09-04 09:09:42 |
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<map>
#include<iostream>
using namespace std;
#define MAXD 1000 + 10
#define INF 10000
char str[MAXD];
int dp[MAXD][MAXD];
int dfs(int start,int last){
if(dp[start][last] != -1)
return dp[start][last];
if(start == last)
return dp[start][last] = 0;
if(str[start] == str[last]){
if(start + 1 == last)
return dp[start][last] = 0;
else
return dp[start][last] = dfs(start + 1 , last - 1);
}
dp[start][last] = INF;
if(last - 1 >= start)
dp[start][last] = min(dp[start][last],dfs(start,last - 1) + 1);
if(start + 1 <= last)
dp[start][last] = min(dp[start][last],dfs(start + 1, last) + 1);
if(start + 1 <= last - 1)
dp[start][last] = min(dp[start][last],dfs(start + 1,last - 1) + 1);
return dp[start][last];
}
int main(){
int T;
scanf("%d",&T);
for(int Case = 1; Case <= T; Case ++){
scanf("%s",str);
memset(dp,-1,sizeof(dp));
int ans = dfs(0,strlen(str) - 1);
printf("Case %d: %d\n",Case,ans);
}
return 0;
}
本文介绍了一种使用动态规划方法来计算将任意字符串转化为回文串所需的最少操作次数。通过递归函数实现状态转移,考虑了删除和添加字符等操作,并提供了完整的C++代码实现。
512

被折叠的 条评论
为什么被折叠?



