uva10617 - Again Palindrome(dp)



再次回文

输入:标准输入

 

输出:标准输出

时间限制: 2秒

 

是àpalindorme的读取相同的从左边,因为它从右侧的一个或多个字符的序列。例如,ŽTOT女士的 回文,但是,ADAM是不是。

 

给定一个序列S Ñ资本拉丁字母。有多少种方法可以有符号数(可能为0)的比分淘汰,其余的序列成为一个palidrome的。 应认为是相同的,唯一不同的顺序得分Varints 。

 

输入

输入文件包含多个测试案例(小于15)。第一行包含一个整数Ţ 表示多少测试用例都遵循。

 

每个ŧ线包含的序列S(1≤N≤60) 。因此,实际上各条生产线是一个测试案例。

 

产量

对于每个测试案例输出一行一个整数 - 号的方法。

 

样例输入                             样例输出

3

BAOBAB

AAAA

ABA

22

15

5

 

 

题意:给定一个字符串,求出字符串中是回文的子字符串。

思路:dp,跟删除字符形成回文有点像。

如果 str[i] == str[j] 那么 dp[i][j] = dp[i + 1][j] + dp[i][j - 1] - dp[i + 1][j - 1] + dp[i + 1][j - 1] + 1 = dp[i + 1][j] + dp[i][j - 1] + 1

如果不相等, 那么dp[i][j] = dp[i + 1][j] + dp[i][j - 1] - dp[i + 1][j - 1]

代码:

 

#include <stdio.h>

#include <string.h>



int t, n, vis[70][70];

long long d[70][70];

char sb[65];

 

long long dp(int i, int j) {

	long long ans = d[i][j];

	if (vis[i][j]) return ans;

	vis[i][j] = 1;

	if (i > j)

		ans = 0;

	else if (i == j)

		ans = 1;

	else if (sb[i] == sb[j]) {

		ans = dp(i + 1, j) + dp(i, j - 1) + 1;

	}

	else {

		ans = dp(i + 1, j) + dp(i, j - 1) - dp(i + 1, j - 1);

	}

	if (ans > d[i][j]) {

		d[i][j] = ans;

	}

	return ans;

}

int main() {

	scanf("%d%*c", &t);

	while (t --) {

		gets(sb);

		n = strlen(sb);

		memset(vis, 0, sizeof(vis));

		memset(d, 0, sizeof(d));

		printf("%lld\n", dp(0, n - 1));

	}

	return 0;

}
 

你可能感兴趣的:(ROM)