uva 11404 dp

UVA 11404 - Palindromic Subsequence



求给定字符串的最长回文子序列,长度一样的输出字典序最小的。

对于 [l, r] 区间的最长回文串。他可能是[l+1, r] 和[l, r-1]两个区间的结果。

或者当s[l] == s[r]时,区间[l+1, r-1]的结果再加上以s[l], s[r]为首尾的子序列。


dp[l][r] = ans(dp[l][r-1], dp[l+1][r], s[l] + dp[l+1][r-1] + s[r]) 
dp存的是子序列,即一个string。


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int MAXN = 1000 + 5;

string s;
string dp[MAXN][MAXN];

void init() {
	for (int i=0; i<MAXN; i++) {
		for (int j=0; j<MAXN; j++) {
			dp[i][j] = "#";
		}
	}
}

string DP(int l, int r) {
	if (dp[l][r] != "#") return dp[l][r];
	if (l > r) return dp[l][r] = "";
	if (l == r) return dp[l][r] = string(1, s[l]);

	string a, b, c, res;

	a = DP(l+1, r);
	b = DP(l, r-1);
	c = DP(l+1, r-1);

	if (a.size() < b.size()) res = b;
	else if (a.size() > b.size()) res = a;
	else if (a < b) res = a;
	else res = b;

	if (s[l] == s[r]) {
		c = string(1, s[l]) + c + string(1, s[r]);
	}
	if (res.size() == c.size()) {
		if (res > c) res = c;
	} else if (res.size() < c.size()) res = c;

	return dp[l][r] = res;
}

int main () {
	for (; cin >> s; ) {

		init();

		string ans = DP(0, s.size()-1);

		cout << ans << endl;
	}
	return 0;
}


posted @ 2017-07-24 19:08  wzjhoutai  阅读(214)  评论(0编辑  收藏  举报