HDU 4632 区间DP 取模

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4632

注意到任意一个回文子序列收尾两个字符一定是相同的,于是可以区间dp,用dp[i][j]表示原字符串中[i,j]位置中出现的回文子序列的个数,有递推关系:

dp[i][j]=dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]

如果i和j位置出现的字符相同,那么dp[i][j]可以由dp[i+1][j-1]中的子序列加上这两个字符构成回文子序列,也就是

dp[i][j]+=dp[i+1][j-1],注意边界特判一下就可以了

(以上摘自杭电解题报告原文)

里面忘了取模,结果输出的是负数,一直WA,然后ans = (ans+10007)%10007;

贴代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #define N 1005
 4 int dp[N][N];
 5 int main()
 6 {
 7     char a[N];
 8     int n;
 9     scanf("%d",&n);
10     for(int t=1; t<=n; ++t)
11     {
12         scanf("%s",a);
13         int len=strlen(a);
14         memset(dp,0,sizeof(dp));
15         for(int i=0; i<len; ++i)
16             dp[i][i] =1;
17         for(int k=1; k<len; ++k)
18         {
19             for(int i=0; i+k <len; ++i)
20             {
21                 int j = i+k;
22                 dp[i][j] += dp[i+1][j] + dp[i][j-1] - dp[i+1][j-1];
23                 if(a[i] == a[j] )
24                     dp[i][j] += (dp[i+1][j-1] + 1);
25                 dp[i][j] %=10007;
26             }
27         }
28         printf("Case %d: %d
",t,(dp[0][len-1]+10007)%10007);
29     }
30     return 0;
31 }
View Code
原文地址:https://www.cnblogs.com/allh123/p/3234865.html