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 }

 

posted on 2013-08-01 21:41  ok_boy  阅读(285)  评论(0编辑  收藏  举报

导航