poj3280_回文dp
题意:给你一串字符,通过添加删除其中的一部分,使其变成一个回文串,并且花费最小(添加删除都有权值)
分析:
因为删除一个字符和添加一个字符时等价的,所以考虑最小的一种即可,
设dp[i][j]表示在区间i j范围内构成回文的最小花费,则:
if 当前匹配的两个字符相等,即str[i] == str[j] 那么dp[i][j] = dp[i+1][j-1]
else
则把左边添加删除一个右边的值
或者在右边添加删除一个左边的值 ,取一个最小的即可
即:dp[i][j]=min(dp[i+1][j]+cost[str[i]-'a'],dp[i][j-1]+cost[str[j]-'a']);
代码:
View Code
1 #include <iostream> 2 #include <string.h> 3 #include <stdio.h> 4 using namespace std; 5 //15896K 79MS 6 const int maxnum=2005; 7 char str[maxnum]; 8 int cost[27]; 9 int dp[maxnum][maxnum]; 10 11 int main() 12 { 13 int n,m,i,j; 14 int a,b; 15 char ch; 16 scanf("%d%d",&n,&m); 17 scanf("%s",str); 18 for(i=0;i<n;i++) 19 { 20 getchar(); 21 scanf("%c%d%d",&ch,&a,&b); 22 cost[ch-'a']=min(a,b); 23 } 24 25 memset(dp,0,sizeof(dp)); 26 for(j=1;j<m;j++) 27 for(i=j-1;i>=0;i--) 28 { 29 if(str[i]==str[j]) 30 dp[i][j]=dp[i+1][j-1]; 31 else 32 dp[i][j]=min(dp[i+1][j]+cost[str[i]-'a'],dp[i][j-1]+cost[str[j]-'a']); 33 } 34 printf("%d\n",dp[0][m-1]); 35 return 0; 36 } 37 38 /* 39 3 4 40 abcb 41 a 1000 1100 42 b 350 700 43 c 200 800 44 */
tjuoj 2822