poj 3280 Cheapest Palindrome (区间Dp)

题意:给出一个由m中字母组成的长度为n的串,给出m种字母添加和删除花费的代价,求让给出的串变成回文串的代价。

分析:我们知道求添加最少的字母让其回文是经典dp问题,转化成LCS求解。这个是一个很明显的区间dp

我们定义dp [ i ] [ j ] 为区间 i 到 j 变成回文的最小代价。

那么对于dp【i】【j】有三种情况

首先:对于一个串如果s【i】==s【j】,那么dp【i】【j】=dp【i+1】【j-1】

其次:如果dp【i+1】【j】是回文串,那么dp【i】【j】=dp【i+1】【j】+min(add【i】,del【i】);

最后,如果dp【i】【j-1】是回文串,那么dp【i】【j】=dp【i】【j-1】 + min(add【j】,del【j】);

dp过程中的细节及递推顺序非常重要,一开始我直接两重循环dp[i][j],i取0到len-1,j取i+1到len-1,

dp[0][0],dp[0][1],dp[0][2],dp[0][3],...dp[0][len-1]

...

dp[len-1][len-1]

这样子是wrong的,因为,比如说,求dp[0][2]的时候,由于dp[0][1]和dp[1][2]的正确值都还没有求出来,所有导致dp[0][2]的结果

错误,正确的做法应该以区间的长度为单位循环,先循环长度为1的,再循环为2到,...

这样才确保每一步正确

还有个细节就是,在循环外dp初始化0,在循环内部dp[i][j]先置为INF,再比较出最优解

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <cmath>
#define maxn 2005
#define maxz 2005
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
int n,len; 
string s;
char ch;
int dp[maxn][maxn];
map<char,int>add,del;
void solve()
{
	memset(dp,0,sizeof(dp));
	for(int k=0;k<len;k++)
	{
		for(int i=0,j=i+k;j<len;j++,i++)
		{
			if(i==j)
			{
				dp[i][j]=0;
				continue;
			}
			dp[i][j]=INF;
			if(s[i]==s[j])
			{
				dp[i][j]=dp[i+1][j-1];
			}
		//	if(dp[i][j-1]==0)
		//	{
				//dp[i][j]=min(dp[i][j],dp[i][j-1]+min(add[s[j]],del[s[j]]));
		//	}
			//if(dp[i+1][j]==0)
			//{
				//dp[i][j]=min(dp[i][j],dp[i+1][j]+min(add[s[i]],del[s[i]]));
			//}
			//if(dp[i][j-1]&&dp[i+1][j])
			//{
				dp[i][j]=min(dp[i][j],min(dp[i][j-1]+min(add[s[j]],del[s[j]]),dp[i+1][j]+min(add[s[i]],del[s[i]])));
			//}
		}
	}
	/*for(int i=0;i<len;i++)
	{
		for(int j=i;j<len;j++)
			cout << dp[i][j] << ' ';
		cout << endl;
	}*/
		
	cout << dp[0][len-1] << endl;
}
int main()
{
   //ios::sync_with_stdio(false);
   while(cin>>n>>len)
   {
   	    cin>>s;
   	    int ac,dc;
   	    add.clear();
   	    del.clear();
   	    for(int i=0;i<n;i++)
   	    {
   	    	cin>>ch>>ac>>dc;
			add[ch]=ac;
			del[ch]=dc;
		}		 
	  	solve();
   }
   return 0;
}

猜你喜欢

转载自blog.csdn.net/wwwlps/article/details/81381791