hdu--4632--dp

dp我突然觉得 没必要将它仔细地分成各种种类 都是利用了差不多什么递推 利用前面计算出来的子结果什么的思想

这题的状态 不难想 因为一个回文串肯定是有左右端点啊 那么就肯定有2维状态了 然后就是递推吧

这边有些初始化 可以先完成 也可以在解决的时候 一并完成 随你

我一开始自己写的是 记忆化搜索的写法. 然后有人写了直接for递推的  速度比我这 递归的快了3倍吧 

我把2种都贴上来  顺便写下 状态转移方程

dp[x][y] = dp[x][y-1] + dp[x+1][y] - dp[x+1][y-1]    if str[x]==str[y]  dp[x][y] += dp[x+1][y-1] + 1;

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 const int size = 1010;
 6 const int mod = 10007;
 7 int len;
 8 char str[size];
 9 int dp[size][size];
10 
11 int dfs( int L , int R )
12 {
13     if( L<1 || R>len || L>R )
14         return 0;
15     if( dp[L][R] )
16         return dp[L][R];
17     if( L==R )
18     {
19         dp[L][R] = 1;
20     }
21     else if( L+1==R )   
22     {
23         if( str[L]==str[R] )
24         {
25             dp[L][R] = 3;
26         }
27         else
28         {
29             dp[L][R] = 2;
30         }
31     }
32     else
33     {
34         if( str[L] == str[R] )
35             dp[L][R] =  ( dfs( L , R-1 )  + dfs( L+1 , R )  + 1 ) % mod ;
36         else
37             dp[L][R] = ( dfs( L , R-1 )  + dfs( L+1 , R ) - dfs( L+1 , R-1 ) + mod ) %mod;
38     }
39     return dp[L][R];
40 }
41 
42 int main()
43 {
44     int t , ans;
45     scanf("%d",&t);
46     for( int k = 1 ; k<=t ; k++ )
47     {
48         cin >> (str+1);
49         len = strlen(str+1);
50         memset( dp , 0 , sizeof(dp) );
51         ans = dfs( 1 , len );
52         printf("Case %d: %d\n",k,ans%mod);
53     }
54     return 0;
55 }
View Code

那个for循环的外层是区间长度 内存是左边端点起始坐标 这个递推顺序一定不能错  你可以根据你的状态转移方程来确定

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 
 5 const int size = 1010;
 6 const int mod = 10007;
 7 int len;
 8 char str[size];
 9 int dp[size][size];
10 
11 void solve( )
12 {
13     for( int i = 1 ; i<=len ; i++ )
14     {
15         for( int j = 1 ; j+i<=len ; j++ )    
16         {
17             if( str[j] == str[i+j] )
18                 dp[j][i+j] = dp[j+1][i+j] + dp[j][i+j-1] + 1;
19             else
20                 dp[j][i+j] = dp[j+1][i+j] + dp[j][i+j-1] - dp[j+1][i+j-1];
21             dp[j][i+j] = (dp[j][i+j]+mod)%mod;
22         }
23     }
24 }
25     
26 int main()
27 {
28     int t , ans;
29     scanf("%d",&t);
30     for( int k = 1 ; k<=t ; k++ )
31     {
32         cin >> (str+1);
33         len = strlen(str+1);
34         memset( dp , 0 , sizeof(dp) );
35         for( int i = 1 ; i<=len ; i++ )
36             dp[i][i] = 1;
37         solve( );
38         printf("Case %d: %d\n",k,dp[1][len]%mod);
39     }
40     return 0;
41 }
View Code

 

 

today:

  11.11   童话里都是骗人的

 

posted @ 2014-11-10 23:06  radical  阅读(136)  评论(0编辑  收藏  举报