码迷,mamicode.com
首页 > 其他好文 > 详细

poj 3280 Cheapest Palindrome DP

时间:2016-04-28 12:07:43      阅读:153      评论:0      收藏:0      [点我收藏+]

标签:

题意:给你一个m位的字符串,其中的字符是给定的n个小写字母之一,然后再字符串中添加或删除这字母的代价

   不一样。求在添加删除操作之后的字符串成为回文串的最小代价。

 

思路:考虑d[i][j]为字符串i到j成为回文串的最小代价。

   如Xx.....yY,如果X == Y,显然d[i][j] = d[i+1][j-1];

   如果X != Y,那么有4种方案:删除X,在Y后面添加一个X,删除Y,在X前面添加Y。从而转移方程可以写成

   d[i][j] = min(d[i+1][j]+del[s[i]-‘a‘], d[i+1][j]+add[s[i]-‘a‘], d[i][j-1] + del[s[j]-‘a‘], d[i][j-1] + add[s[j]-‘a‘]);

   由上面的方程可以分析得,对于删除添加字符s[i],我们只用取得其中最小的代价的操作就可以了,从而方程就更短了

   如d[i][j] = min(d[i+1][j]+cost[s[i]-‘a‘], d[i][j-1] + cost[s[j]-‘a‘]);

 

AC代码:

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int M = 2005;
int n,m,ch[2],cost[27],d[M][M];
char s[M];
void solve()
{
	memset(d, 0, sizeof(d));
	
	for(int dis = 1; dis < m; dis++)
	{
		for(int i = 0, j = i+dis; j < m; i++,j++)
		{
			if(s[i] == s[j]) d[i][j] = d[i+1][j-1];
			else{
				d[i][j] = min(d[i+1][j] + cost[s[i]-‘a‘], d[i][j-1] + cost[s[j]-‘a‘]);
			}
		}
	}
	printf("%d\n", d[0][m-1]);
}
int main()
{
	while(~scanf("%d %d", &n, &m))
	{
		memset(cost, 0, sizeof(cost));
		scanf("%s", s);
		for(int i = 0; i < n; i++)
		{
			int t1,t2;
			scanf("%s %d %d", ch,&t1, &t2);
			cost[ch[0]-‘a‘] = min(t1,t2);
		}
		solve();
	}
	return 0;
}

 

poj 3280 Cheapest Palindrome DP

标签:

原文地址:http://www.cnblogs.com/sevenun/p/5441758.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!