[NOIP 2015] 子串

[题目链接]

              http://uoj.ac/problem/149

[算法]

         动态规划

         f[i][j][k][0 / 1]表示在A的前i位中选j个互不重叠的子串,与B的前k位相同,第i位选 / 不选的方案数

         可以用滚动数组优化空间复杂度

[代码]

        

#include<bits/stdc++.h>
using namespace std;
#define MAXN 1010
#define MAXM 210
const int P =  1000000007;

int i,j,k,x,n,m,t;
long long f[2][MAXM][MAXM][2];
char a[MAXN],b[MAXM];

int main() 
{
        
        scanf("%d%d%d",&n,&m,&t);
        scanf("%s%s",a + 1,b + 1);
        f[0][0][0][0] = 1;
        for  (i = 1; i <= n; i++)
        {
                for (j = 0; j <= min(i,t); j++)
                {
                        for (k = 0; k <= m; k++)
                        {
                                f[i & 1][j][k][0] = f[i & 1][j][k][1] = 0;
                                f[i & 1][j][k][0] = (1ll * f[(i - 1) & 1][j][k][0] + 1ll * f[(i - 1) & 1][j][k][1]) % P;
                                if (j == 0 || k == 0) continue;
                                if (a[i] == b[k]) f[i & 1][j][k][1] = (1ll * f[(i - 1) & 1][j - 1][k - 1][0] + 1ll * f[(i - 1) & 1][j - 1][k - 1][1] + 1ll * f[(i - 1) & 1][j][k - 1][1]) % P;
                        }
                }        
        } 
        printf("%lld\n",(f[n & 1][t][m][0] + f[n & 1][t][m][1]) % P);
         
        return 0;
    
}

 

转载于:https://www.cnblogs.com/evenbao/p/9493526.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值