UVA 10453 Make Palindrome(区间dp-补全回文串+打印结果)

题目大意:给一个字符串,要求添加最少个字符,把它变成回文串,并输出。

思路:
区间dp,dp[i][j] 表示区间(i, j) 内的字符串添加的最少个数,
变成回文串那么,
如果str[i]==str[j], dp[i][j] = dp[i+1][j-1] + 1
否则dp[i][j] = min{dp[i+1][j], dp[i][j-1]} + 1;
题目要输出方案,那么只要再开一个数组,根据状态转移递归输出即可


#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1005;
char str[N];
int dp[N][N];
void print_path(int l,int r) {
	if(l > r) {
		return ;
	}
	if(l == r) {
		putchar(str[l]);
	}else if(str[l] == str[r]) {
		putchar(str[l]);
		print_path(l+1,r-1);
		putchar(str[r]);
	}else if(dp[l+1][r] > dp[l][r-1]){
		putchar(str[r]);
		print_path(l,r-1);
		putchar(str[r]);
	}else {
		putchar(str[l]);
		print_path(l+1,r);
		putchar(str[l]);
	}
}
int main() {
	int cas = 0;
	while(scanf("%s",str) != EOF) {
		int len = strlen(str);
		memset(dp,0,sizeof(dp));
		for(int i = 0; i <= len; i++) {
			dp[i][i] = 1;
		}
		for(int l = len-1; l >= 0; l--) {
			for(int r = l; r < len; r++) {
				if(str[l] == str[r]) {
					dp[l][r] = dp[l+1][r-1];
				}else if(dp[l+1][r] > dp[l][r-1]){
					dp[l][r] = dp[l][r-1]+1;
				}else {
					dp[l][r] = dp[l+1][r]+1;
				}
			}
		}
		printf("%d ",dp[0][len-1]);
		print_path(0,len-1);
		printf("\n");
	}
	return 0;
}


你可能感兴趣的:(uva,10453)