NKOI 3559 子串
来源:互联网 发布:java多线程日志输出 编辑:程序博客网 时间:2024/06/05 21:49
【NOIP2015 Day2】子串
Time Limit:10000MS Memory Limit:131072K
Total Submit:2 Accepted:2
Case Time Limit:1000MS
Description
有两个仅包含小写英文字母的字符串A和B。现在要从字符串A中取出k个互不重叠的非空子串,然后把这k个子串按照其在字符串A中出现的顺序依次连接起来得到一个新的字符串,请问有多少种方案可以使得这个新串余字符串B相等?注意:子串取出的位置不同也认为是不同的方案。
Input
/*输入文件名为substring.in。*/
第一行是三个正整数n,m,k,分别表示字符串A的长度,字符串B的长度,以及问题描述中所提到的k,每两个整数之间用一个空格隔开。
第二行包含一个长度为n的字符串,表示字符串A。
第三行包含一个长度为m的字符串,表示字符串B。
Output
/*输出文件名为substring.out。*/
输出共一行,包含一个整数,表示所求方案数。由于答案可能很大,所以这里要求输出答案1,000,000,007取模的结果。
Sample Input
样例输入1:6 3 1aabaabaab样例输入2:6 3 2aabaabaab样例输入3:6 3 3aabaabaab
Sample Output
样例输出1:2样例输出2:7样例输出3:7
Hint
输入输出样例说明:
所有合法方案如下:(加下划线的部分表示取出的子串)
样例1:aab aab / aab aab
样例2:a ab aab / a aba ab / a a ba ab / aab a ab / aa b aab / aa baa b / aab aa b
样例3:a a b aab / a a baa b / a ab a a b / a aba a b / a a b a a b / a a ba a b / aab a a b
数据规模与约定:
对于第1组数据:1<=n<=500, 1<=m<=50, k=1;
对于第2组至第3组数据:1<=n<=500, 1<=m<=50, k=2;
对于第4组至第5组数据:1<=n<=500, 1<=m<=50, k=m;
对于第1组至第7组数据:1<=n<=500, 1<=m<=50, 1<=k<=m;
对于第1组至第9组数据:1<=n<=1000, 1<=m<=100, 1<=k<=m;
对于所有10组数据:1<=n<=1000, 1<=m<=200, 1<=k<=m。
Source
感谢nodgd手打题目
首先我们看的出来这是一道动归
∑ f[k-1][p][j-1] 条件:A[i]==B[j]且A[i-1]!=B[j-1] 0<p<i
∑ f[k-1][p][j-1]+f[k][i-1][j-1] 条件:A[i]==B[j]且A[i-1]==B[j-1] 0<p<i
我们可以用一个Sum[ ][ ][ ]数组来记录下来,避免重复计算,
Sum[k][i][j] = dp[k][i][j] + Sum[k][i-1][j];
时间复杂度可降至 O(nmk)
#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int mod=1000000007;int K,n,m;char a[1005],b[205];int f[2][1005][205],sum[2][1005][205];int main(){scanf("%d%d%d",&n,&m,&K);scanf("%s%s",a+1,b+1);int i,j,k;f[0][0][0]=1;for(i=0;i<=n;i++) sum[0][i][0]=1;/////////初始化for(k=1;k<=K;k++){memset(sum[k&1],0,sizeof(sum[k&1]));memset(f[k&1],0,sizeof(f[k&1]));for(i=1;i<=n;i++) for(j=1;j<=m;j++){ if(a[i]==b[j]){ f[k&1][i][j]=sum[(k-1)&1][i-1][j-1]; if(a[i-1]==b[j-1]) f[k&1][i][j]=(f[k&1][i][j]+f[k&1][i-1][j-1])%mod;}sum[k&1][i][j]=(sum[k&1][i][j]+f[k&1][i][j]+sum[k&1][i-1][j])%mod;}}int ans=0;for(i=1;i<=n;i++) ans=(ans+f[K&1][i][m])%mod;cout<<ans;}
- NKOI 3559 子串
- NKOI 3686 最大子段和
- NKOI 1941 最长递增子序列
- NKOI 3659 硬币
- NKOI 1006 护卫队
- NKOI 1123 潜水员
- NKOI 1011 锁妖塔
- NKOI 1023 生命游戏
- NKOI 1036 回文词
- NKOI 1228 丛林道路
- NKOI 2202 字符串乘方
- NKOI 2151 烽火传递
- NKOI 2149 布丁
- NKOI 1086 细胞分裂
- NKOI 3587 全排列
- NKOI 2152 滑动窗口
- NKOI 1349 工作安排
- NKOI 1759 监狱
- android ImageLoader加载本地图片的工具类
- JQuery选择器中的可见性筛选
- test
- CodeForces 366A Dima and Guards(结构体,数学)
- HDU 2612 Find a way(BFS)
- NKOI 3559 子串
- Android官方MVP架构示例项目解析
- 机器学习 -- 多元回归实现实例
- C语言执行shellcode的五种方法
- 由Tomcat 8005端口想到的...
- 安卓小案例收集一
- PAT 甲级 1019 General Palindromic Number(简单题)
- IBM MQ 发送 和 接收
- jackson学习