hdu 4632 Palindrome subsequence (区间dp)

版权声明:转载注明下出处就行了。 https://blog.csdn.net/LJD201724114126/article/details/89247795

题目链接:哆啦A梦传送门

题意:给一个字符串,找出这个字符串中有多少个子串是回文?子串可以相同(只要取得位置有不同的就行)

题解:

区间dp。

我们设 dp[i][j] 为区间 [i,j] 的回文数有多少?

那么就有转移方程:

dp[i][j]=dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]。 (因为dp[i+1][j]与dp[i][j-1] 可能有公共部分,故我们还需减去 dp[i+1][j-1])

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

#include<bits/stdc++.h>
using namespace std;

const int mod=10007;

int dp[1010][1010];
char str[1010];

int main()
{

    int ncase,T=0;
    cin>>ncase;

    while(ncase--)
    {
        cin>>str;

        int n=strlen(str);

        memset(dp,0,sizeof(dp));

        for(int i=0;i<n;i++)
            dp[i][i]=1;

            ///枚举长度len
        for(int i=1;i<=n;i++)
        {
            ///枚举起点j,终点 j+i-1
            for(int j=0;j+i-1<n;j++)
            {
                
                dp[j][j+i-1]=(dp[j+1][j+i-1]+dp[j][j+i-2]-dp[j+1][j+i-2]+mod)%mod;
                if(str[j]==str[j+i-1])
                    dp[j][j+i-1]=(dp[j][j+i-1]+dp[j+1][j+i-2]+1)%mod;
//                printf("%d %d %d \n",j,j+i-1,dp[j][j+i-1]);
            }
        }

        printf("Case %d: %d\n",++T,dp[0][n-1]);


    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/LJD201724114126/article/details/89247795