题意:
求一个串的回文子序列有多少个。
题解:
dp[i][j]表示[i,j]区间回文子序列的个数。
dp[i][j] = dp[i+1][j] + dp[i][j-1] - dp[i+1][j-1];
if(str[i] == str[j]) dp[i][j] = dp[i+1][j-1] + 1;
不断从内往外推,一旦存在str[i]==str[j]那么要加上dp[i+1][j-1]。
莫名其妙,比赛的时候大数据没过,之后从新写了一遍就过了。
#include<iostream> #include<math.h> #include<stdio.h> #include<algorithm> #include<string.h> #include<string> #include<vector> #include<queue> #include<map> #include<set> #include<stack> #define B(x) (1<<(x)) using namespace std; typedef long long ll; typedef unsigned long long ull; const int oo = 0x3f3f3f3f; const ll OO = 0x3f3f3f3f3f3f3f3f; const double eps = 1e-9; #define lson rt<<1 #define rson rt<<1|1 void cmax(int& a, int b){ if (b>a)a = b; } void cmin(int& a, int b){ if (b<a)a = b; } void cmax(ll& a, ll b){ if (b>a)a = b; } void cmin(ll& a, ll b){ if (b<a)a = b; } void cmax(double& a, double b){ if (a - b < eps) a = b; } void cmin(double& a, double b){ if (b - a < eps) a = b; } void add(int& a, int b, int mod){ a = (a + b) % mod; } void add(ll& a, ll b, ll mod){ a = (a + b) % mod; } const int MOD = 100007; const int maxn = 1100; char str[maxn]; int dp[maxn][maxn]; int main(){ //freopen("E:\\read.txt", "r", stdin); int T, cas = 1; scanf("%d", &T); while (T--){ scanf("%s", str + 1); int n = strlen(str + 1); memset(dp, 0, sizeof dp); for (int j = 1; j <= n; j++){ dp[j][j] = 1; for (int i = j - 1; i >= 1; i--){ dp[i][j] = (dp[i + 1][j] + dp[i][j - 1] - dp[i + 1][j - 1] + MOD) % MOD; if (str[i] == str[j]) dp[i][j] = (dp[i][j] + dp[i + 1][j - 1] + 1) % MOD; } } printf("Case #%d: %d\n", cas++, dp[1][n]); } return 0; }