hdu 4632 (dp)

来源:互联网 发布:尼尔森数据查询 编辑:程序博客网 时间:2024/04/30 10:43


Sample Input
4
a
aaaaa
goodafternooneveryone
welcometoooxxourproblems
 


Sample Output
Case 1: 1
Case 2: 31
Case 3: 421
Case 4: 960
 
题意:
一个字符串,有多少个subsequence是回文串。
题解:
      用dp[i][j]表示这一段里有多少个回文串,
    1 ,  左边的a[i]对回文串个数没影响的情况    dp[i][j] = dp[i+1][j] ;
     2.  右边的a[j]对回文串个数没影响的情况   dp[i][j] = dp[i][j-1];

    3.   a[i],a[j]对回文串有影响,即a[i]==a[j] 时则  dp[i][j] = dp[i+][j-]+dp[i+1][j-1]+1   ;   (其中一个dp[i+1][j+1]是原来i+1和j-1这段的回文,两头加了a[i],a[j])  以后 

         又变成新的回文,相当于多又多了 dp[i+1][j-1] 个回文 ,  而a[i]a[j]又是一个回文, 所以再加一 ,)

     4.  因为 1,2,3里 都包含了 区间 dp[i+1][j-1] ,所以可能有重复,所以减去 dp[i+1][j-1] ;只留一个dp[i+1][j-1] ;
   综上   :      a[i]!=d[j]    -->    dp[i][j] = dp[i+1][j] + dp[i][j-1] - dp[i+1][j-1];

                 a[i]==d[j]    -->   dp[i][j] = dp[i+1][j] + dp[i][j-1]  + 1  ;  (本来1,2,3,加起来有4个dp[i+1][j-1],减去三个后 .. ..)    


#include<cstdio>#include<cstring>#include<map>#include<vector>#include<cmath>#include<cstdlib>#include<stack>#include<queue>#include<iostream>#include<algorithm>using namespace std ;const int MOD = 10007;int dp[1100][1100];char str[1100];int len ;int solve(int l , int r){if(l>r) return 0 ;if(l==r) return dp[l][r]=1 ;if(dp[l][r] != -1 ) return  dp[l][r] ;if(l == r-1){if(str[l]==str[r])     return dp[l][r]=3 ;else  return dp[l][r]=2 ;     }dp[l][r] = solve(l+1,r)+solve(l,r-1);if(dp[l][r] >= MOD ) dp[l][r] -= MOD ;if( str[l]== str[r]){   dp[l][r]++ ;   if(dp[l][r] >= MOD ) dp[l][r] -= MOD ;}else {dp[l][r] -= solve(l+1,r-1) ;if(dp[l][r] < 0 ) dp[l][r] += MOD ;}return dp[l][r]; }int main(){int t , Case = 0;scanf("%d",&t);while(t--){        Case++;     memset(dp,-1,sizeof(dp));scanf("%s",str);len = strlen(str);printf("Case %d: %d\n",Case , solve(0,len-1));}return 0 ;}






        
原创粉丝点击