vijos1327 回文词

描述

回文词是一种对称的字符串——也就是说,一个回文词,从左
到右读和从右到左读得到的结果是一样的。任意给定一个字符串,
通过插入若干字符,都可以变成一个回文词。你的任务是写一个程
序,求出将给定字符串变成回文词所需插入的最少字符数。
比如字符串“Ab3bd”,在插入两个字符后可以变成一个回文
词(“dAb3bAd”或“Adb3bdA”)。然而,插入两个以下的字符无
法使它变成一个回文词。

格式

输入格式

第一行包含一个整数N,表示给定字符串的长度,3<=N<=5000
第二行是一个长度为N的字符串,字符串由大小写字母和数字
构成。

输出格式

一个整数,表示需要插入的最少字符数。

样例1

样例输入1[复制]

5
Ab3bd

样例输出1[复制]

2

限制

各个测试点1s


解析
对于一个序列S只要看它的左右端的字符是否相同,如果相同那么就看除掉两端字符的新串要添的字符个数了;如果不同,就在它左面添上右断的字符然后考虑去掉新序列两端的字符后的串要添的字符。或者在右面添上左端的字符,在考虑去掉添了字符后新串左右两端字符得到的新串要添的字符。
设计一个二维状态opt[L,i]表示长度是L+1,起点是i的序列变成回文词要添的字符的个数。阶段就是字符的长度,决策要分类,即S[i] 和S[i+L]是否相等。

if( s[j] != s[i+j] ) f[j][i] = min( f[j+1][i-1], f[j][i-1] ) + 1; //添加一个让他变成回文串
else f[j][i] = f[j+1][i-2]; //左右两边的相等就直接是去掉边界的回文串
#include
#include
#include

using namespace std;

#define LOCAL

int f[5010][5010],N;//f[i][j] means start from i end at i+j
char s[5010];
void Dynamic_Planning()
{
	memset(f,0,sizeof(f));
	for(int i=1; i


你可能感兴趣的:(动态规划)