UVA 10617 Again Palindromes (区间dp)

题意:给你n个串(最长不超过60),问有多少种删去字符的方法使剩下的字符成为一个回文子串。

解析:
设dp[l][r]为从l到r有多少个回文串。
当str[l] != str[r]时,我们要考虑(l+1,r)组成的回文串,(l,r-1)之间的回文串,但是两者都会计算(x+1,y-1)的回文串数,所以要减去(x+1,y-1)的回文串数,
dp[l][r] = dp[l+1][r] + dp[l][r-1] - dp[l+1][r-1];

当str[l] == str[r]时,一直递推下去,然后由于中间的子串可能为空,则在删除的操作上+1,dp[l][r] = dp[l+1][r] + dp[l][r-1] + 1;

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 100;
char str[N];
ll dp[N][N];
int main() {
	int T;
	scanf("%d",&T);
	while(T--) {
		scanf("%s",str);
		int len = strlen(str);
		for(int i = 0; i <= len; i++) {
			dp[i][i] = 1;
		}
		for(int l = len-1; l >= 0; l--) {
			for(int r = l+1; r < len; r++) {
				if(str[l] == str[r]) {
					dp[l][r] = dp[l+1][r] + dp[l][r-1] + 1;
				}else {
					dp[l][r] = dp[l+1][r] + dp[l][r-1] - dp[l+1][r-1];
				}
			}
		}
		printf("%lld\n",dp[0][len-1]);
	}
	return 0;
}



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