标签:
字串S长M,由N个小写字母构成。欲通过增删字母将其变为回文串,增删特定字母花费不同,求最小花费。
思路:1.先对普遍情况进行讨论 ,即不管内部是否回文的花费 :dp[i][j]=min(dp[i+1][j]+cost[s[i]-‘a‘],dp[i][j-1]+cost[s[j]-‘a‘]);
2.讨论后,如果内部的序列已经是回文。那么实际上的花费更小:dp[i][j]=min(dp[i][j],dp[i+1][j-1]);
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<string> 5 using namespace std; 6 int dp[2050][2050]; 7 int cost[38]; 8 int main() 9 { 10 int N,M; 11 cin>>N>>M; 12 //用string时,头文件用的是string 不是cstring 13 string s; 14 cin>>s; 15 for(int i=0;i<N;i++) 16 { 17 char ch; 18 int add1,delete1; 19 cin>>ch>>add1>>delete1; 20 //对字母的花费的数组角标设置 21 cost[ch-‘a‘]=min(add1,delete1); 22 } 23 for(int i=M-1;i>=0;i--) 24 { 25 for(int j=i+1;j<M;j++) 26 { 27 //先对普遍情况进行讨论 ,即不管内部是否回文的花费 28 dp[i][j]=min(dp[i+1][j]+cost[s[i]-‘a‘],dp[i][j-1]+cost[s[j]-‘a‘]); 29 //讨论后,如果内部的序列已经是回文。那么实际上的花费更小 30 if(s[i]==s[j]) 31 { 32 dp[i][j]=min(dp[i][j],dp[i+1][j-1]); 33 } 34 35 } 36 } 37 cout<<dp[0][M-1]<<endl; 38 return 0; 39 } 40
标签:
原文地址:http://www.cnblogs.com/xlsryj/p/4761352.html