• [Noip2015]子串


    [Noip2015]子串

    一.前言

    ​ 呜呜呜呜我不要写字符串哇哇哇……题目链接

    二.思路

    ​ 其实跟某诡异字符串算法差不多,(f_{i,j,k}) 表示在 a 中前 i 个字符取出 k 个子串完美匹配了 (b[1...j]) 的方案数,但是这题为了方便转移子串数,最好加一维 0/1 表示 (a_i) 有没有用。

    ​ 设出来状态就很好做了,分情况讨论8~。

    首先是 (f_{i,j,k,0}) ,反正当前位都不选,k 和 j 都不会增加,前一个的抉择都无所谓了,直接继承

    [f_{i,j,k,0}=f_{i-1,j,k,1}+f_{i-1,j,k,0} ]

    然后是 (f_{i,j,k,1}) ,既然要选,先要看 (a_i) 能不能匹配 (b_j) 不能匹配直接白给,方案为 0.如果可以匹配的话,接上就好,此时既可以自成一段亦可以和前一个接起来。

    [f_{i,j,k,1}=f_{i-1,j-1,k,1}+f_{i-1,j-1,k-1,1}+f_{i-1,j-1,k-1,0} ]

    但是内存会爆炸,考虑到每次只用了前一个,(mod 2) 滚掉一维就行。

    三.CODE

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<fstream>
    #include<cmath>
    using namespace std;
    int read(){
    	char ch=getchar();
    	int res=0,f=1;
    	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    	for(;ch>='0'&&ch<='9';ch=getchar())res=res*10+(ch-'0');
    	return res*f;
    }
    const int mod=1000000007;
    int n,m,K,sum,f[1005][205][205][2];
    char a[1005],b[205];
    int main(){
    	scanf("%d%d%d
    ",&n,&m,&K);
    	for(int i=1;i<=n;++i){
    		f[i][0][0][0]=1;
    		scanf("%c",&a[i]);
    	}
    	f[0][0][0][0]=1;
    	scanf("
    ");
    	for(int i=1;i<=m;++i)scanf("%c",&b[i]);
    	for(int i=1;i<=n;++i){
    		int now=i%2,pre=(i-1)%2;
    		for(int j=1;j<=m&&j<=i;++j){
    			for(int k=1;k<=K&&k<=j;++k){
    				f[now][j][k][0]=(f[pre][j][k][0]+f[pre][j][k][1])%mod;
    				if(a[i]==b[j]){
    					f[now][j][k][1]=((f[pre][j-1][k-1][0]+
    					  f[pre][j-1][k][1])%mod+f[pre][j-1][k-1][1])%mod;	
    				}
    				else f[now][j][k][1]=0;
    			}
    		}
    	}
    	cout<<(f[n%2][m][K][0]+f[n%2][m][K][1])%mod; 
    	return 0;
    } 
    
  • 相关阅读:
    php解析.csv文件
    sublime text3 输入中文的解决方法
    git 的使用
    yii2.0 框架邮件的发送
    yii2.0的分页和排序
    php上传图片文件常用的几个方法
    在yii框架中如何连接数据库mongodb
    yii框架中验证器声明一组内置验证器可以使用短名称引用
    yii中的cookie的发送和读取
    ExpressionToSQL
  • 原文地址:https://www.cnblogs.com/clockwhite/p/13493468.html
Copyright © 2020-2023  润新知