zoukankan      html  css  js  c++  java
  • 【HDU4632】Palindrome subsequence【区间DP】

    题目大意:

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4632
    给出tt个字符串,求每个字符串的回文子串个数。


    思路:

    这种题一看就是区间DP,只可惜想不到方程。
    f[i][j](ij)f[i][j](i\leq j)表示iijj的区间的回文子串个数。
    那么如何转移呢?
    肯定是[i,k][i,k]区间会问子串个数+[k,j][k,j]区间回文子串个数+两区间交界处回文子串个数。
    那么由于kk[i,j][i,j]的任意位置都不会影响答案(这道题很明显不会有多个解取最值),所以最好找到一个最容易计算答案的kk
    那么这个kk要么是i+j2\frac{i+j}{2},要么肯定用容斥原理。
    经过思考,后者更容易计算。根据容斥,很明显可以得到:
    f[i][j]=f[i+1][j]+f[i][j1]f[i+1][j1](s[i]!=s[j])f[i][j]=f[i+1][j]+f[i][j-1]-f[i+1][j-1](s[i]!=s[j])
    那么如果s[i]=s[j]s[i]=s[j]呢?
    那么中间的那一块(f[i+1][j1]f[i+1][j-1])中的每一个回文子串都会受到影响。所以就有:
    f[i][j]=f[i+1][j]+f[i][j1]f[i+1][j1]+f[i+1][j1]+1f[i][j]=f[i+1][j]+f[i][j-1]-f[i+1][j-1]+f[i+1][j-1]+1

    f[i][j]=f[i+1][j]+f[i][j1]+1f[i][j]=f[i+1][j]+f[i][j-1]+1
    那么也可以将两个方程合二为一:
    f[i][j]=f[i+1][j]+f[i][j1]f[i+1][j1]+(s[i1]==s[j1]?f[i+1][j1]+1:0)f[i][j]=f[i+1][j]+f[i][j-1]-f[i+1][j-1]+(s[i-1]==s[j-1]?f[i+1][j-1]+1:0)
    注意题目中说了取模。而且要注意负数取模!
    f[i][j]=((f[i+1][j]+f[i][j1]f[i+1][j1]+(s[i1]==s[j1]?f[i+1][j1]+1:0))%MOD+MOD)%MODf[i][j]=((f[i+1][j]+f[i][j-1]-f[i+1][j-1]+(s[i-1]==s[j-1]?f[i+1][j-1]+1:0))\%MOD+MOD)\%MOD


    代码:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #define N 1010
    #define MOD 10007
    using namespace std;
    
    int f[N][N],t,len;
    char s[N];
    
    int main()
    {
    	scanf("%d",&t);
    	for (int l=1;l<=t;l++)
    	{
    		cin>>s;
    		for (int i=1;i<=strlen(s);i++)
    		 f[i][i]=1;  //每个长度为1的子串有1个回文串(它本身)
    		for (int i=strlen(s)-1;i>0;i--)  //左端点
    		 for (int j=i+1;j<=strlen(s);j++)  //右端点
    		  f[i][j]=((f[i+1][j]+f[i][j-1]-f[i+1][j-1]+(s[i-1]==s[j-1]?f[i+1][j-1]+1:0))%MOD+MOD)%MOD;
    		printf("Case %d: %d\n",l,f[1][strlen(s)]%MOD);
    	}
    	return 0;
    }
    
  • 相关阅读:
    bzoj3224
    [洛谷日报第62期]Splay简易教程 (转载)
    bzoj1588
    codeforces467C
    codeforces616B
    codeforces379C
    codeforces545C
    codeforces285C
    codeforces659C
    快读代码level.2
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998546.html
Copyright © 2011-2022 走看看