hihocoder 1323 - 回文字符串 - [hiho一下162周][區間dp]
阿新 • • 發佈:2017-08-12
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 intlen=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]