阿巴阿巴

NegaNebulus 2020-07-31 10:08:45 2020-07-31 10:25:30

{菜^{菜^{菜^{菜^{菜^{菜^菜}}}}}}

#include<bits/stdc++.h>
using namespace std;
const int N=1005,M =205,mo=1000000007;
int n,m,K;
bool val=1;
char a[N],b[M ];
int f[2][M ][M ][2];/*f[i][j][k][0/1]
表示串a 中截止到i位使用k 个子串匹配串b 前j位字符,且串a 第i位选or不选的方案数*/  

int main()
{
    cin>>n>>m>>K;     
    for(int i=1;i<=n;i++)
    	cin>>a[i];
    for(int i=1;i<=m;i++)
    	cin>>b[i];
    
    f[0][0][0][0]=f[1][0][0][0]=1;//初始化 
    
    //dp
    //无论如何,当第i位不选时 f[i][j][k][0]=f[i-1][j][k][0]+f[i-1][j][k][1]
    //当a[i]==b[j]时,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]
    //因为每次状态转移只会用 f[i-1][j][k][0/1] 和 f[i][j][k][0/1],所以有了空间优化 
	for(int i=1;i<=n;i++,val^=1/*错开*/){
        for(int j=1;j<=m;j++){
            for(int k=1;k<=K;k++){
                f[val][j][k][0]=(f[val^1][j][k][0]+f[val^1][j][k][1])%mo;
				//状态转移 
                if(a[i]==b[j]){ 
                    f[val][j][k][1]=(f[val^1][j-1][k][1]+(f[val^1][j-1][k-1][0]+f[val^1][j-1][k-1][1])%mo)%mo;
					//状态转移 
                }
                else{//当然不选 
                    f[val][j][k][1]=0;
                }
            }
        }
    } 
    cout<<(f[n&1][m][K][1]+f[n&1][m][K][0])%mo;//输出f[n][m][k][1]+f[n][m][k][0]
    return 0;
}

共 11 条回复

NegaNebulus

我再来

{菜^{菜^{菜^{菜^{菜^{菜^菜}}}}}}