1. 程式人生 > >【題解】洛谷P1435 迴文子串(區間dp)

【題解】洛谷P1435 迴文子串(區間dp)

IOI 2000的題目 實際上是一道區間dp

我們設dp[i][j]代表字串中第i個字元到第j個字元得到迴文串需要新增的字元數,初始化dp[i][i]為0。這裡注意還應該初始化dp[i][i+1],如果s[i]==s[i+1]那麼dp[i][i+1]=0,否則=1。接著我們列舉不相鄰的兩個點,如果兩個字元相同那麼dp[i][j]就等價於dp[i+1][j-1]。否則就等於這一段去掉首字元在尾加上1與去掉尾字元在頭加上1的最小值,狀態轉移更新即可。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
using namespace std;
string s;
int dp[1010][1010];
int main()
{
	cin>>s;
	int len=s.size();
//	memset(dp,0x3f3f3f3f,sizeof(dp));
	for(int i=0;i<len;i++)
	{
		dp[i][i]=0;
	}
	for(int i=0;i<len-1;i++)
	{
		if(s[i]==s[i+1]) dp[i][i+1]=0;
		else dp[i][i+1]=1;		
	}
	for(int i=2;i<len;i++)
	{
		for(int j=0;j+i<len;j++)
		{
			int k=j+i;
			if(s[j]==s[k]) dp[j][k]=dp[j+1][k-1];
			else dp[j][k]=min(dp[j+1][k]+1,dp[j][k-1]+1);
		}
	}
	printf("%d",dp[0][len-1]);
	return 0;
}