Sample Input
6
tanbirahmed
shahriarmanzoor
monirulhasan
syedmonowarhossain
sadrulhabibchowdhury
mohammadsajjadhossain
Sample Output
Case 1: 5
Case 2: 7
Case 3: 6
Case 4: 8
Case 5: 8
Case 6: 8
题意:给出一个字符串,可以添加删除字符,或替换字符,求把它变成回文的最少操作次数。
dp[i][j]表示字符i到j位置上最少需要几步构成回文。
分两种情况讨论: 1.str[i] == str[j],此时则直接用上一步的值进行更新这一步,即dp[i][j] = dp[i+1][j-1]
2.str[i]!=str[j],此时可以有两种操作,替换,删除,状态转移方程为dp[i][j] = min(min(dp(i+1,j),dp(i,j-1),dp(i+1,j-1))
动规
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
const int INF = 0x3f3f3f3f;
using namespace std;
int dp[1010][1010];
int n,len;
char str[1010];
int main()
{
int Case = 0;
scanf("%d",&n);
while(n --)
{
scanf("%s",str);
len = strlen(str) - 1;
memset(dp,0,sizeof(dp));
for(int i = len; i >= 0; i --)
for(int j = i + 1; j <= len; j ++)
if(str[i] == str[j])
dp[i][j] = dp[i+1][j-1];
else
dp[i][j] = min(min(dp[i+1][j],dp[i][j-1]),dp[i+1][j-1]) + 1;
printf("Case %d: %d\n",++ Case,dp[0][len]);
}
return 0;
}
记忆化搜索
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
const int INF = 0x3f3f3f3f;
using namespace std;
int dp[1010][1010];
int n,len;
char str[1010];
int DFS(int x,int y)
{
if(x <= y) ///结束条件
{
if(x == y || (x + 1 == y && str[x] == str[y]))
{
dp[x][y] = 0;
return dp[x][y];
}
if(dp[x][y] != INF) ///减枝
return dp[x][y];
if(str[x] == str[y])
dp[x][y] = min(dp[x][y],DFS(x + 1,y - 1));
else
{
if(DFS(x + 1,y) < dp[x][y])
dp[x][y] = DFS(x + 1,y);
if(DFS(x,y - 1) < dp[x][y])
dp[x][y] = DFS(x,y-1);
if(DFS(x + 1,y - 1) < dp[x][y])
dp[x][y] = DFS(x + 1,y - 1);
dp[x][y] += 1;
}
return dp[x][y];
}
return INF;
}
int main()
{
int Case = 0;
scanf("%d",&n);
while(n --)
{
scanf("%s",str);
len = strlen(str);
memset(dp,INF,sizeof(dp));
printf("Case %d: %d\n",++ Case,DFS(0,len-1));
}
return 0;
}
</span>
UVA10739 String to Palindrome(区间DP + 递推)
最新推荐文章于 2020-03-17 09:09:10 发布