51nod1092(lcs简单运用/dp)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1092

 

题意:中文题诶~

 

思路:

解法1:最坏的情况就是在原字符串的右边添加该字符串的倒序字符串咯,长度为a.size(),不难想到原字符串和其倒序字符串可能存在公共子序列,公共子序列含有的字符我们是不需要添加的(因为两边原本就有嘛).我们要使添加的字符最少,那么就是找到最大的公共子序列,再用a.size()减去公共子序列含有的字符数目就好啦,即:

ans=a.size()-lcs(a, b), 其中b为a的倒序字符串;

 

代码:

 1 #include <bits/stdc++.h>
 2 #define MAXN 1010
 3 using namespace std;
 4 
 5 int dp[MAXN][MAXN];
 6 
 7 int main(void){
 8     string a, b;
 9     cin >> a;
10     b=a;
11     reverse(b.begin(), b.end());
12     int len=a.size();
13     for(int i=0; i<len; i++){
14         for(int j=0; j<len; j++){
15             if(a[i]==b[j]){
16                 dp[i+1][j+1]=dp[i][j]+1;
17             }else{
18                 dp[i+1][j+1]=max(dp[i+1][j], dp[i][j+1]);
19             }
20         }
21     }
22     cout << len-dp[len][len] << endl;
23 }

 

解法2:

我们可以用dp[i][j]存储从第i个字符开始长度为j的字符串变成会文串需要添加的最少字符,那么初始化:

dp[0][j]=0, dp[1][j]=0,长度为0,1的字符串自然是回文串啦;

状态转移方程式为:

if(a[j]==a[i+j-1]  dp[i][j]=dp[i-1][j+1]

else dp[i][j]=min(dp[i-1][j], dp[i-1][j+1])+1

这些还是比较好理解的,直接上代码好了..

 

代码:

 1 #include <bits/stdc++.h>
 2 #define MAXN 1010
 3 using namespace std;
 4 
 5 int dp[MAXN][MAXN]; //***dp[i][j]存储从第j个字符开始,长度为i的字符串变成回文串最少需要添加的字符数
 6 
 7 int main(void){
 8     string a;
 9     cin >> a;
10     int len=a.size();
11     for(int i=2; i<=len; i++){
12         for(int j=0; j<len; j++){
13             if(a[j]==a[j+i-1]){
14                 dp[i][j]=dp[i-2][j+1];
15             }else{
16                 dp[i][j]=min(dp[i-1][j], dp[i-1][j+1])+1;
17             }
18         }
19     }
20     cout << dp[len][0] << endl;
21     return 0;
22 }

 

posted @ 2017-01-14 19:17  geloutingyu  阅读(309)  评论(0编辑  收藏  举报