Bootstrap

【动态规划,最长公共子序列】P1435 [IOI2000] 回文字串

Step 0 前言

明天csp考试了,来写篇题解加加rp

step 1 题目简介

给你一个长度为 l l l 1 ≤ l ≤ 1000 1 \le l \le 1000 1l1000)的字符串,求需要添加几个字符使它成为回文字符串。

Step 2 题意解释

考虑到题目中的样例:Ab3bd
而最优的结果是:dAb3bAd

  • 可以发现,中间这一段回文字符留着是最优的

那我们可以考虑反转原序列:db3bA
我们惊奇的发现中间这一段回文字符是不会变的

  • 即使回文字符不在一起也不是不行,比如:Abd3b,反转后是:b3dbA,最优解是:Abd3dbA。

手模完这组数据后,我们可以发现这题就是求一个串的反串的最长公共子序列,那么DP诞生了!

step 3 AC code

#include<bits/stdc++.h>
#define ll long long

using namespace std;

char s[1005],s1[1005];
int dp[1005][1005];
int n;

int main(){
	//ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	scanf("%s",s + 1);
	int n = strlen(s + 1);
	//cout << n <<"\n";
	for(int i = n; i >= 1; i-- )
		s1[i] = s[n - i + 1];
	for(int i = 1; i <= n ;i++){
		for(int j = 1; j <= n; j++){
			if(s[i] == s1[j]) dp[i][j] = dp[i - 1][j - 1] + 1;
			else dp[i][j] = max(dp[i - 1][j],dp[i][j - 1]); 
		}
	}
	printf("%d",n - dp[n][n]);
	return 0;
}

最后祝各位oier明天RP++!!!

;