Lightoj 1025 - The Specials Menu (区间DP)

题目链接:

  Lightoj 1025 - The Specials Menu

题目描述:

  给出一个字符串,可以任意删除位置的字符,也可以删除任意多个。问能组成多少个回文串?

解题思路:

  自从开始学dp,感觉自己智商一直处于离线状态。席八啊啊啊啊啊啊!今天随机到这个题目,看了好久竟然没有看出来是区间DP。知道是区间DP后立马感觉明白。

  情景设定 dp[l][r] 表示 区间 [l, r] 内的回文串数目。

  状态转移:dp[l][r] = dp[l][r-1] + dp[l+1][r], 但是这样会加重复的,所以要减去dp[l+1][r-1], 当a[l] == a[r]的时候,对于区间[l, r]之间的回文串,就可以变成以a[l]与a[r]结尾的,然后就需要加上。

 1 #include <queue>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 
 7 using namespace std;
 8 typedef long long LL;
 9 const int maxn = 70;
10 const int INF = 0x3f3f3f3f;
11 LL dp[maxn][maxn];
12 char a[maxn];
13 
14 int main ()
15 {
16     int T;
17     scanf ("%d", &T);
18     for (int t=1; t<=T; t++)
19     {
20         scanf ("%s", a+1);
21         int len = strlen (a+1);
22         memset (dp, 0, sizeof(dp));
23 
24         for (int i=1; i<=len; i++)
25             for (int l=1; l+i-1<=len; l++)
26             {
27                 int r = l + i - 1;
28                 dp[l][r] += dp[l+1][r];
29                 dp[l][r] += dp[l][r-1];
30 
31                 if (a[l] == a[r])   dp[l][r] += 1;
32                 else    dp[l][r] -= dp[l+1][r-1];
33                 
34             }
35         printf ("Case %d: %lld\n", t, dp[1][len]);
36     }
37     return 0;
38 }

 

posted @ 2015-11-09 16:20  罗茜  阅读(411)  评论(0编辑  收藏  举报