HDU4632
1 /* 2 区间dp 3 dp[i][j]表示这个区间组成的子串是回文串的个数*/ 4 #include<stdio.h> 5 #include<string.h> 6 const int maxn=1010; 7 int mod=10007; 8 int dp[maxn][maxn]; 9 void init(int len) 10 { 11 memset(dp, 0, sizeof(dp)); 12 for(int i = 0; i < len; ++i) 13 { 14 dp[i][i] = 1;//处理一个字符的情况 15 } 16 } 17 int main() 18 { 19 int i,j,n,m,k; 20 char s[maxn]; 21 int t,cas=0; 22 scanf("%d",&t); 23 while(t--) 24 { 25 scanf("%s",s); 26 m=strlen(s); 27 init(m); 28 for(i=1;i<m;i++) 29 { 30 for(j=0;j<m&&j+i<m;j++) 31 { 32 if(s[j]==s[i+j]) 33 { 34 dp[j][i+j]=(dp[j+1][i+j]+dp[j][i+j-1]+1)%mod; 35 36 } 37 /*d[i, j] = d[i, j -1] + d[i + 1, j] - d[i + 1, j - 1] + 1 + d[i + 1, j - 1], 38 (1 + d[i + 1, j - 1])中间的那些和两头的能构成回文串,两头对回文贡献为1, 39 (d[i, j -1] + d[i + 1, j] - d[i + 1, j - 1] )这是两头不能构成回文的个数 40 所以这整个区间的就是这个表达式*/ 41 else 42 { 43 dp[j][i+j]=(dp[j+1][i+j]+dp[j][i+j-1]-dp[j+1][i+j-1])%mod; 44 } 45 /*这时候的d[i][i + p] 存的是不能和两头构成回文串的*/ 46 } 47 } 48 printf("Case %d: %d\n",++cas,(dp[0][m-1]%mod+mod)%mod);//dp[0][m-1]可能是负数 49 } 50 return 0; 51 }