1. 程式人生 > >hihocoder 1323 - 回文字符串 - [hiho一下162周][區間dp]

hihocoder 1323 - 回文字符串 - [hiho一下162周][區間dp]

std space 第一個 不難 sin 回文字符串 spa scanf 情況

用dp[i][j]表示把[i,j]的字符串str改寫成回文串需要的最小操作步數。

並且假設所有dp[ii][jj] (ii>i , jj<j)都為已知,即包括dp[i+1][j]、dp[i][j-1]、dp[i+1][j-1]這三者都已知,則:

1、

如果str[i]==str[j],那麽dp[i][j]=dp[i+1][j-1];

2、

否則dp[i][j]可以分為:

  ①“一個字符”+“一個回文串”型:那麽我們可以在str[i,j]後面加上一個字符,或者刪去第一個字符來使得其變成回文串,這種情況即dp[i+1][j]+1;

  ②“一個回文串”+“一個字符”型:那麽我們可以在str[i,j]前面加上一個字符,或者刪去最後一個字符來使得其變成回文串,這種情況即dp[i][j-1]+1;

  ③“一個字符”+“一個回文串”+“另一個字符”型:那麽我們就修改第一個或者修改最後一個字符,這種情況即dp[i+1][j-1]+1;

這三種情況中,選擇最小的那個,就是dp[i][j]的值。

故不難得到:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 int dp[105][105];
 6 char str[105];
 7 int main()
 8 {
 9     scanf("%s",str+1);
10     int
len=strlen(str+1); 11 memset(dp,0,sizeof(dp)); 12 for(int k=2;k<=len;k++) 13 { 14 for(int i=1,j=i+k-1;j<=len;i++,j++) 15 { 16 if(str[i]==str[j]) dp[i][j]=dp[i+1][j-1]; 17 else dp[i][j]=min( min(dp[i+1][j]+1,dp[i][j-1]+1),dp[i+1][j-1]+1 ); 18 }
19 } 20 printf("%d\n",dp[1][len]); 21 }

hihocoder 1323 - 回文字符串 - [hiho一下162周][區間dp]