[NOIP2015提高组]子串 DP
2017-11-02 19:34
330 查看
题目描述
有两个仅包含小写英文字母的字符串 A 和 B。现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一 个新的字符串,请问有多少种方案可以使得这个新串与字符串 B 相等?注意:子串取出 的位置不同也认为是不同的方案。
有两个仅包含小写英文字母的字符串 A 和 B。现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一 个新的字符串,请问有多少种方案可以使得这个新串与字符串 B 相等?注意:子串取出 的位置不同也认为是不同的方案。
题解:
简单DP。状态表示以及转移见代码。代码:
#include<bits/stdc++.h> using namespace std; #define LL long long #define pa pair<int,int> const int Maxn=1010,Maxm=210,Maxk=210,mod=1e9+7; const int inf=2147483647; int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} return x*f; } int n,m,K,pos[26][Maxm],len[26]; char A[Maxn],B[Maxm]; int f[Maxm][Maxk],g[2][Maxm][Maxk]; //f[j][k] B串匹配到j 分了k段 的方案数 //g[j][k] B串匹配到j 分了k段 且上一位有选的方案数 int main() { n=read();m=read();K=read(); scanf("%s%s",A+1,B+1); for(int i=1;i<=m;i++)pos[B[i]-'a'][++len[B[i]-'a']]=i; f[0][0]=1; int now=0; for(int i=1;i<=n;i++) { int x=A[i]-'a';now^=1; memset(g[now],0,sizeof(g[now])); for(int j=1;j<=len[x];j++) { int p=pos[x][j],lim=min(p,K);//匹配到p for(int k=1;k<=lim;k++)//分了k段 g[now][p][k]=(f[p-1][k-1]+g[now^1][p-1][k])%mod; //新分一段 和前面的一段合在一起 } int lim1=min(i,m),lim2=min(i,K); for(int j=0;j<=lim1;j++) for(int k=0;k<=lim2;k++) f[j][k]=(f[j][k]+g[now][j][k])%mod; } printf("%d",f[m][K]); }
相关文章推荐
- LuoguP2679[NOIP2015] 子串 解题报告【多维DP】
- Luogu P2679 [NOIp提高组2015]子串
- 【NOIP2015提高组Day2】子串
- UOJ149【NOIP2015】子串 (DP)
- NOIP2015提高组Day2 第二题 子串 解题报告
- uoj149【2015提高】子串(dp)
- NOIP 2015 子串 (DP)
- NOIP2015复赛提高组day2(A:跳石头 B:子串 C:运输计划)
- noip 2015 T5 子串 字符串dp
- 【NOIP】提高组2015 子串
- NOIP2015 子串 dp
- 【uoj#149】【NOIP2015】子串 DP
- [NOIP2015] 提高组 洛谷P2679 子串
- NOIP2015提高组T2 子串
- 【NOIP2015】子串(字符串DP)
- NOIP2015 子串 解题报告(DP)
- NOIP2015 子串【DP】【NOIP】
- 【UOJ#149】【NOIP2015】子串【计数DP】
- [UOJ#149][NOIP2015]子串(dp)
- NOIP2015 子串 (DP+优化)