poj 3280 Cheapest Palindrome DP
题目连接:http://poj.org/problem?id=3280
题意就是给你一个字符串,含有n个字母,每个字母可以添加可以去除,添加和删除字母有花费,问组成一个回文串。
思路就是每个回文串的最大子串必定有一个开头一个结尾位置,最终位置为0~len-1,这样但是每一对起始位置都会有一个回文长度,对每一个长度进行搜就可以了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <stdlib.h> 6 #include <vector> 7 #include <set> 8 #include <queue> 9 #include <stack> 10 #define loop(s,i,n) for(i = s;i < n;i++) 11 #define cl(a,b) memset(a,b,sizeof(a)) 12 using namespace std; 13 using namespace std; 14 const int maxn = 2005; 15 16 int dp[maxn][maxn]; 17 int add[30], del[30]; 18 19 int main(){ 20 int n, m, i, j, len; 21 char c, str[maxn]; 22 cin >> n >> m >> str; 23 loop(0,i,n) 24 { 25 cin >> c; 26 cin >> add[c-'a'] >> del[c-'a']; 27 } 28 loop(1,len,m) 29 for(i = 0; i + len < m; i ++){ 30 j = i + len; 31 if(str[i] == str[j]){ 32 dp[i][j] = dp[i+1][j-1]; 33 }else{ 34 dp[i][j] = min( 35 min(dp[i+1][j]+add[str[i]-'a'], dp[i][j-1]+add[str[j]-'a']), 36 min(dp[i+1][j]+del[str[i]-'a'], dp[i][j-1]+del[str[j]-'a'])); 37 } 38 } 39 cout<<dp[0][m-1]<<endl; 40 return 0; 41 }