• [NOIp2015]子串


    Description

    Luogu2679
    (A)中选出(k)个非空子串且连起来是(B)的方案数。

    Solution

    这个题可以仿照最长公共子序列来定义状态(f_{i,j,k})表示(A)串的前(i)个和(B)串的前(j)个匹配,且用了(k)个子串,并且必须选(A_i)。但是这样并不是很好转移。
    所以我们添加一个辅助状态(s_{i,j,k})表示(A)串的前(i)个和(B)串的前(j)个匹配,且用了(k)个子串,但是不一定选(A_i)。于是就有如下几种转移:

    (A_i = B_j),则(f_{i,j,k} = f_{i-1,j-1,k} + s[i-1][j-1][k-1])(分别对应(A_i)(A_{i-1})组合成一个子串或者是单独成一个子串),否则(f_{i,j,k} = 0)
    而无论如何,(s_{i,j,k} = f_{i, j, k} + s_{i-1,j,k})

    Code

    #include <cstdio>
    
    typedef long long ll;
    const int N = 1010;
    const int M = 210;
    const ll MOD = 1e9 + 7;
    
    ll f[M][M][2];
    char a[N], b[M];
    int n, m, k;
    
    int main() {
    	scanf("%d%d%d", &n, &m, &k);
    	scanf("%s", a+1); scanf("%s", b+1);
    	f[0][0][0] = f[0][0][1] = 1;
    	for (int i = 1; i <= n; ++i)
    		for (int j = m; j; --j)
    			for (int K = k; K; --K) {
    				if (a[i] == b[j])
    					f[j][K][0] = (f[j-1][K][0] + f[j-1][K-1][1]) % MOD;
    				else f[j][K][0] = 0;
    				
    				f[j][K][1] = (f[j][k][1] + f[j][K][0]) % MOD;
    			}
    	printf("%lld
    ", f[m][k][1] % MOD);
    }
    
    

    Note

    这个题我一开始提交的时候写的是%I64d错了一次,后来又因为忘记取模错了一次。这些小问题还是要仔细。

  • 相关阅读:
    getSupportFragmentManager要用在FragmentActivity及其子类中
    nginx 配置php
    openwrt 安装 ser2net 配置
    stm32 hid 键盘描述
    外部中断实验
    stm32 UART串口
    stm32 按键
    小结-stm32 驱动LED灯
    ASCII 计算机码
    debian/ubuntu安装桌面环境
  • 原文地址:https://www.cnblogs.com/wyxwyx/p/noip201522.html
Copyright © 2020-2023  润新知