【HDU4632】Palindrome subsequence【區間DP】
阿新 • • 發佈:2018-11-09
題目大意:
題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=4632
給出
個字串,求每個字串的迴文子串個數。
思路:
這種題一看就是區間DP,只可惜想不到方程。
設
表示
到
的區間的迴文子串個數。
那麼如何轉移呢?
肯定是
區間會問子串個數+
區間迴文子串個數+兩區間交界處迴文子串個數。
那麼由於
在
的任意位置都不會影響答案(這道題很明顯不會有多個解取最值),所以最好找到一個最容易計算答案的
。
那麼這個
要麼是
,要麼肯定用容斥原理。
經過思考,後者更容易計算。根據容斥,很明顯可以得到:
那麼如果
呢?
那麼中間的那一塊(
)中的每一個迴文子串都會受到影響。所以就有:
即
那麼也可以將兩個方程合二為一:
注意題目中說了取模。而且要注意負數取模!
程式碼:
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 1010
#define MOD 10007
using namespace std;
int f[N][N],t,len;
char s[N];
int main()
{
scanf("%d",&t);
for (int l=1;l<=t;l++)
{
cin>>s;
for (int i=1;i<=strlen(s);i++)
f[i][i]=1; //每個長度為1的子串有1個迴文串(它本身)
for (int i=strlen(s)-1;i>0;i--) //左端點
for (int j=i+1;j<=strlen(s);j++) //右端點
f[i][j]=((f[i+1][j]+f[i][j-1]-f[i+1][j-1]+(s[i-1]==s[j-1]?f[i+1][j-1]+1:0))%MOD+MOD)%MOD;
printf("Case %d: %d\n",l,f[1][strlen(s)]%MOD);
}
return 0;
}