zoukankan      html  css  js  c++  java
  • P2679 子串 DP

    P2679 子串 DP

    从字符串A中取出(k)段子串,按原顺序拼接,问存在多少个方案使拼接的字符串与字符串B相同

    淦,又是这种字符串dp

    设状态(ans[i][j][k])表示A串位置(i),B串位置(j),已取出(k)段字符串,不管当前位置(i)是否能匹配上的方案数,(g[i][j][k])表示A串位置(i),B串位置(j),已取出(k)段字符串,当前A串位置(i)已匹配上B串位置(j)(即(a[i]==b[j]))的方案数。

    状态转移:

    if(a[i]==b[j]) // 如果匹配上了
        g[i][j][p]=(g[i-1][j-1][p]+ans[i-1][j-1][p-1])%MOD;
    	// g[i-1][j-1][p] 表示与上一个匹配连在一起
    	// ans[i-1][j-1][p-1] 以前的方案数
    else g[i][j][p]=0;
    
    ans[i][j][p]=(g[i][j][p]+ans[i-1][j][p])%MOD;	
    // g[i][j][p] 现在新匹配上的
    // ans[i-1][j][p] 以前的方案数
    

    然后为了优化空间就上了滚动数组,见代码:

    #include <cstdio>
    #define MAXN 1010
    #define MOD 1000000007
    using namespace std;
    int n,m,k;
    int ans[3][MAXN][MAXN],g[3][MAXN][MAXN];
    char a[MAXN],b[MAXN];
    int main(){
    	scanf("%d %d %d", &n, &m, &k);
    	scanf("%s%s", a+1, b+1);
    	int cur=1;
    	ans[0][0][0]=1;
    	for(int i=1;i<=n;++i){
    		ans[cur][0][0]=1;
    		for(register int j=1;j<=m;++j)
    			for(register int p=1;p<=k;++p){
    				if(a[i]==b[j]) g[cur][j][p]=(g[cur^1][j-1][p]+ans[cur^1][j-1][p-1])%MOD;
    				else g[cur][j][p]=0;
    				ans[cur][j][p]=(g[cur][j][p]+ans[cur^1][j][p])%MOD;
    			}
    		cur^=1;
    	}
    	printf("%d
    ", ans[cur^1][m][k]);
    	return 0;
    }
    
  • 相关阅读:
    jquery toggle(listenerOdd, listenerEven)
    struts quick start
    hdu 1518 Square (dfs)
    hdu 2544 最短路 (最短路径)
    hdu 1754 I Hate It (线段树)
    hdu 1856 More is better (并查集)
    hdu 1358 Period (KMP)
    hdu 2616 Kill the monster (DFS)
    hdu 2579 Dating with girls(2) (bfs)
    zoj 2110 Tempter of the Bone (dfs)
  • 原文地址:https://www.cnblogs.com/santiego/p/11437162.html
Copyright © 2011-2022 走看看