HDU 4632 Palindrome subsequence(DP)

题目链接

做的我很无奈,当时思路很乱,慌乱之中,起了一个想法,可以做,但是需要优化。尼玛,思路跑偏了,自己挖个坑,封榜之后,才从坑里出来,过的队那么多,开始的时候过的那么快,应该就不是用这种扯淡方法做的。

  1 表示很无奈,没有想到简单的递推式,搞了一个MLE+TLE的方法。
  2 最初版本,多了一个for的复杂度,只要标记一下就好,可是在递归了不好处理,让我折腾了老一会,才弄好。
  3 复制代码
  4 int dfs(int l,int r)
  5 {
  6     int i,ans = 0;
  7     if(l == r)
  8         return 1;
  9     else if(l > r)
 10         return 0;
 11     if(dp[l][r])
 12         return dp[l][r];
 13     ans = dfs(l+1,r)+1;
 14     for(i = l+1; i <= r; i ++)
 15     {
 16         if(str[l] == str[i])
 17             ans = (ans + dfs(l+1,i-1) + 1)%MOD;
 18     }
 19     dp[l][r] = ans;
 20     return ans;
 21 }
 22 
 23 终于在3点多,改成了递推版本。然后MLE了。
 24 复制代码
 25 for(i = 0; i < len; i ++)
 26 {
 27     dp[i][i] = 1;
 28     sum[i][i][str[i]-'a'] = 1;
 29 }
 30 for(i = 1; i < len; i ++)
 31 {
 32     for(j = 0; j < len-i; j ++)
 33     {
 34         dp[j][i+j] = (dp[j+1][i+j] + 1 + sum[j+1][i+j][str[j]-'a'])%MOD;
 35     }
 36     for(j = 0; j < len; j ++)
 37     {
 38         if(j == 0) continue;
 39         k = str[j-1]-'a';
 40         if(i+j-1 == len) break;
 41         if(str[i+j] == str[j-1])
 42             sum[j][i+j][k] = (sum[j][i+j-1][k] + dp[j][i+j-1] + 1)%MOD;
 43         else
 44             sum[j][i+j][k] = sum[j][i+j-1][k];
 45     }
 46 }
 47 printf("Case %d: %d\n",cas++,dp[0][len-1]);
 48 
 49 终于又改了改,A了。改的,我都看不懂这是什么意思了。
 50 #include <cstdio>
 51 #include <cstring>
 52 #include <ctime>
 53 #include <cstdlib>
 54 #include <string>
 55 #include <queue>
 56 #include <map>
 57 #include <algorithm>
 58 using namespace std;
 59 #define MOD 10007
 60 char str[1010];
 61 int dp[1010][1010],sum[1010][1010][26];
 62 int sum1[1010][26];
 63 int sum2[1010][26];
 64 int main()
 65 {
 66     int len,t,cas = 1,i,j,k;
 67     scanf("%d",&t);
 68     while(t --)
 69     {
 70         scanf("%s",str);
 71         len = strlen(str);
 72         for(i = 0; i < len; i ++)
 73         {
 74             for(j = 0; j < len; j ++)
 75                 dp[i][j] = 0;
 76         }
 77         for(i = 0; i < len; i ++)
 78         {
 79             for(j = 0; j < 26; j ++)
 80                 sum1[i][j] = sum2[i][j] = 0;
 81         }
 82         for(i = 0; i < len; i ++)
 83         {
 84             dp[i][i] = 1;
 85             sum1[i][str[i]-'a'] = 1;
 86         }
 87         for(i = 1; i < len; i ++)
 88         {
 89             if(i%2 == 1)
 90             {
 91                 for(j = 0; j < len-i; j ++)
 92                 {
 93                     dp[j][i+j] = (dp[j+1][i+j] + 1 + sum1[j+1][str[j]-'a'])%MOD;
 94                 }
 95                 for(j = 0; j < len; j ++)
 96                 {
 97                     if(j == 0) continue;
 98                     k = str[j-1]-'a';
 99                     if(i+j-1 == len) break;
100                     if(str[i+j] == str[j-1])
101                         sum2[j][k] = (sum1[j][k] + dp[j][i+j-1] + 1)%MOD;
102                     else
103                         sum2[j][k] = sum1[j][k];
104                 }
105             }
106             else
107             {
108                 for(j = 0; j < len-i; j ++)
109                 {
110                     dp[j][i+j] = (dp[j+1][i+j] + 1 + sum2[j+1][str[j]-'a'])%MOD;
111                 }
112                 for(j = 0; j < len; j ++)
113                 {
114                     if(j == 0) continue;
115                     k = str[j-1]-'a';
116                     if(i+j-1 == len) break;
117                     if(str[i+j] == str[j-1])
118                         sum1[j][k] = (sum2[j][k] + dp[j][i+j-1] + 1)%MOD;
119                     else
120                         sum1[j][k] = sum2[j][k];
121                 }
122             }
123         }
124         printf("Case %d: %d\n",cas++,dp[0][len-1]);
125     }
126     return 0;
127 }

 

posted @ 2013-08-02 11:28  Naix_x  阅读(222)  评论(0编辑  收藏  举报