题意:给你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];
解析:
设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;
}
本文介绍了一种使用动态规划解决寻找字符串中回文子串数量问题的算法。通过递推公式计算不同长度的子串中回文串的数量,并讨论了字符匹配情况对计算的影响。
614

被折叠的 条评论
为什么被折叠?



