P2679 [NOIP2015 提高组] 子串

>>a串中 取连续的的不重叠字串首尾相连组成 b串

f[i][j][k]->a的前i位且i必选 取k串  组成 b的前j位  的方案数

 呢村会炸 <=1e7,8

令g[i][j][k]=Σf[i-t][j-t][k-1] -> g[i][j][k]=g[i-1][j][k]+f[i][j][k]->A前i个中选出k组匹配上B中的前j个最后一位选/不选都可以的方案数

>>>因为不重叠 所以完全背包-> f[][j-t][k-1] 前一个状态 所以不能影响

 

#include <cstdio>
#define MAXN 1010
#define MAXM 210
using namespace std;
const int MOD=1e9+7;
int n,m,k;
char a[MAXN],b[MAXM];
int f[MAXM][MAXM]; //a到n, b到m, 取了k串
int g[MAXM][MAXM]; //f的前缀和
inline int min(int a,int b) { return a<b ? a : b; }

int main() {
    scanf("%d%d%d",&n,&m,&k);
    scanf("%s%s",a+1,b+1);
    g[0][0]=1;f[0][0]=1; 
    for (int i=1;i<=n;i++) {
        for (int j=min(m,i);j>=1;j--) {
            for (int p=min(k,j);p>=1;p--) {
                f[j][p]=a[i]==b[j] ? (f[j-1][p]+g[j-1][p-1])%MOD : 0;
                g[j][p]=(g[j][p]+f[j][p])%MOD;
            }
        }
    }
    printf("%d\n",g[m][k]);
    return 0;
}

 

posted @ 2023-09-03 09:44  JMXZ  阅读(10)  评论(0)    收藏  举报