NOIP 2015 子串 (DP)

来源:互联网 发布:脑洞网络用语 编辑:程序博客网 时间:2024/06/08 10:30

Description

有两个仅包含小写英文字母的字符串 A 和 B。现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一 个新的字符串,请问有多少种方案可以使得这个新串与字符串 B 相等?(子串取出的位置不同也认为是不同的方案)

Solution

显然DP,
dp[i][j][k][0/1]表示当前已经计算到A串中的第i个字母,B串中的第j个字母,已经用了k次机会以及当前的第i个字符是否被选中。
边界:dp[i][0][0][0]=1
转移就非常显然了吧
dp[i][j][k][0]=dp[i1][j][k][0]+dp[i1][j][k][1]
如果A[i]=B[j]dp[i][j][k][1]=dp[i1][j1][k1][0]+dp[i1][j1][k][1]+dp[i1][j1][k1][1]
否则,dp[i][j][k][1]=0

Code

#include<cstdio>#include<cstdlib>#include<cmath>#include<cstring>#include<iostream>#include<algorithm>#include<queue>#include<vector>#include<set>#define For(i , j , k) for (int i = (j) , _##end_ = (k) ; i <= _##end_ ; ++ i)#define Fordown(i , j , k) for (int i = (j) , _##end_ = (k) ; i >= _##end_ ; -- i)#define Set(a , b) memset(a , b , sizeof(a))#define pb push_back#define INF (0x3f3f3f3f)#define Mod (1000000007)using namespace std;typedef long long LL;template <typename T> inline bool chkmax(T &a , T b) { return a < b ? (a = b , 1) : 0; }template <typename T> inline bool chkmin(T &a , T b) { return b < a ? (a = b , 1) : 0; }int _ , __;char c_;inline int read(){    for (_ = 0 , __ = 1 , c_ = getchar() ; !isdigit(c_) ; c_ = getchar()) if (c_ == '-') __ = -1;    for ( ; isdigit(c_) ; c_ = getchar()) _ = (_ << 1) + (_ << 3) + (c_ ^ 48);    return _ * __;}inline void file(){#ifdef hany01    freopen("string.in" , "r" , stdin);    freopen("string.out" , "w" , stdout);#endif}const int maxn = 1001 , maxm = 201;int n , m , K , dp[maxn][maxm][maxm][2] , t;char s1[maxn] , s2[maxm];int main(){    file();    n = read();    m = read();    K = read();    scanf("%s" , s1 + 1);    scanf("%s" , s2 + 1);    dp[0][0][0][0] = dp[1][0][0][0] = 1;    t = 0;    For(i , 1 , n)    {        t ^= 1;        For(j , 1 , i)            For(k , 1 , min(j , K))            {                dp[t][j][k][0] = (dp[t ^ 1][j][k][0] + dp[t ^ 1][j][k][1]) % Mod;                if (s1[i] == s2[j])                    dp[t][j][k][1] = ((dp[t ^ 1][j - 1][k - 1][0] + dp[t ^ 1][j - 1][k][1]) % Mod + dp[t ^ 1][j - 1][k - 1][1]) % Mod;                else                    dp[t][j][k][1] = 0;            }    }    printf("%d\n" , (dp[t][m][K][0] + dp[t][m][K][1]) % Mod);    return 0;}
原创粉丝点击