zoukankan      html  css  js  c++  java
  • [P2679][NOIP2015T5] 子串 (DP+滚动数组)

    题意:给出两个字符串,求用第一个字符串中的子串去匹配第二个子串,而且第一个字符串的子串在匹配第二个字符串时要按顺序;

    用滚动数组来优化DP,否则会MLE;

    设f[i][j][k][0/1]表示是否一定使用了A串中的第 i个字符,并用了A中的 k个子串来匹配 B串中的前 j个字符(0表示一定不用当前这个字符,而1表示一定用);

    状态转移方程:

    f[i][j][k][0]=f[i−1][j][k][0]+f[i−1][j][k][1];

    if(a[i]==b[j])   f[i][j][k][1]=f[i−1][j−1][k−1][1]+f[i−1][j−1][k−1][0]+f[i−1][j−1][k][1];

    附上代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int mod = 1000000007;
    const int N = 1011;
    
    int n,m,sum;
    int f[2][N][N][2];
    char a[N],b[N];
    
    int main()
    {
    	scanf("%d%d%d",&n,&m,&sum);
    	scanf("%s%s",a+1,b+1);
    	f[0][0][0][0]=1;//初始化 
    	for(int i=1;i<=n;i++){
    		int op=i&1;
    		f[op][0][0][0]=1;//初始化 
    		for(int j=1;j<=min(i,m);j++)
    		for(int k=1;k<=min(j,sum);k++){
    			f[op][j][k][0]=f[op][j][k][1]=0;//滚动数组覆盖 
    			f[op][j][k][0]=(f[op^1][j][k][0]+f[op^1][j][k][1])%mod;
    			if(a[i]==b[j]){
    				f[op][j][k][1]=((f[op^1][j-1][k-1][1]+f[op^1][j-1][k-1][0])%mod+f[op^1][j-1][k][1])%mod;
    			}
    		}
    	}
    	printf("%d",(f[n&1][m][sum][1]+f[n&1][m][sum][0])%mod);
    	return 0;
    }
    
  • 相关阅读:
    函数与递归、第五章习题
    第四章习题continue、break
    程序异常处理
    第一章习题
    第三章习题.split('')
    文本进度条
    字符串处理函数、Unicode
    字符串处理.<方法>()
    springbatch
    卸载gitlab
  • 原文地址:https://www.cnblogs.com/nnezgy/p/11366372.html
Copyright © 2011-2022 走看看