【noip2015】【DP】子串
来源:互联网 发布:网络调试助手使用说明 编辑:程序博客网 时间:2024/06/05 21:06
子串
描述
有两个仅包含小写英文字母的字符串 A 和 B。现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一 个新的字符串,请问有多少种方案可以使得这个新串与字符串 B 相等?注意:子串取出的位置不同也认为是不同的方案。
格式
输入格式
第一行是三个正整数 n,m,k,分别表示字符串 A 的长度,字符串 B 的长度,以及问 题描述中所提到的 k,每两个整数之间用一个空格隔开。第二行包含一个长度为 n 的字符串,表示字符串 A。 第三行包含一个长度为 m 的字符串,表示字符串 B。
输出格式
输出共一行,包含一个整数,表示所求方案数。由于答案可能很大,所以这里要求输 出答案对 1,000,000,007 取模的结果。
样例1
样例输入1
6 3 1
aabaab
aab样例输出1
2
样例2
样例输入2
6 3 2
aabaab
aab样例输出2
7
样例3
样例输入
6 3 3
aabaab
aab样例输出3
7
限制
对于第 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。提示
样例 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来源
NOIP 2015 提高组 Day 2 第二题
DP题,我竟然不会,QAQ
明明是个不复杂的DP我却想了好久,果然蒟蒻无比
先说一下滚动前的方程式
dp[0/1][i][j][k]表示dp到n的第i个字符,m的第j个字符,选了k个串有多少个情况,第一个0表示不选当前位,1表示选
然后方程式:
dp[0][i][j][k]=dp[0][i-1][j][k]+dp[1][i-1][j][k]
if(n[i]==m[j])dp[1][i][j][k]=dp[1][i-1][j-1][k]+dp[0][i-1][j-1][k-1]+dp[1][i-1][j-1][k-1]
故意写这么大因为我看小字就头晕,找到个字大的才看懂
然后一定要注意初始化,最复杂的一部分,不选第一位要初始化为n在i以前与m[1]相等的字符数量,如果n[i]==m[1],选就初始化为1
其他的看代码就可以懂了,我就不多说了
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<set>#include<map>#include<queue>#include<algorithm>#include<vector>#include<cstdlib>#include<cmath>#include<ctime>#include<stack>#define INF 2100000000#define ll long long#define clr(x) memset(x,0,sizeof(x))#define maxclr(x) memset(x,127,sizeof(x))using namespace std;inline int read(){ char c; int ret=0; while(!(c>='0'&&c<='9')) c=getchar(); while(c>='0'&&c<='9') { ret=(c-'0')+(ret<<1)+(ret<<3); c=getchar(); } return ret;}#define M 1005#define N 205#define P 1000000007int dp[2][N][N],f[2][2][N][N];int m,n,k,t,sum;char sn[M],sm[N];void DP(){ for(int i=1;i<=n;i++) { for(int j=m;j>=2;j--)//倒着推为了滚动 for(int o=1;o<=k;o++) { dp[0][j][o]=(dp[0][j][o]+dp[1][j][o])%P; if(sn[i]==sm[j]) dp[1][j][o]=((dp[1][j-1][o]+dp[0][j-1][o-1])%P+dp[1][j-1][o-1])%P; else dp[1][j][o]=0; } dp[0][1][1]=t;//初始化当前位前m第一位的情况 if(sn[i]==sm[1])//初始化当前位去第一位的情况 { t++; dp[1][1][1]=1; } else dp[1][1][1]=0; }}int main(){ freopen("substring.in","r",stdin); freopen("substring.out","w",stdout); n=read();m=read();k=read(); scanf("%s\n%s",sn+1,sm+1); DP(); printf("%d\n",(dp[0][m][k]+dp[1][m][k])%P); return 0;}
大概就是这个样子,如果有什么问题,或错误,请在评论区提出,谢谢。
- 【noip2015】【DP】子串
- NOIP2015 子串 DP
- noip2015 子串 dp
- NOIP2015 子串 dp
- [DP] NOIP2015 子串
- [noip2015]子串(dp)
- NOIP2015 子串【DP】【NOIP】
- 【uoj#149】【NOIP2015】子串 DP
- 【UOJ#149】【NOIP2015】子串【计数DP】
- NOIP2015 子串 解题报告(DP)
- [UOJ#149][NOIP2015]子串(dp)
- Noip2015 Day1 T2 子串(Dp)
- 洛谷 2676 [NOIP2015] 子串 DP
- UOJ149【NOIP2015】子串 (DP)
- 【DP】UOJ#149 【NOIP2015】子串
- [NOIP2015提高组]子串 DP
- code vs 4560 NOIP2015 D2T2 子串 (dp)
- 【codevs 4560】[NOIP2015 D2T2]子串(dp)
- Pick Several Elements From a Vector Randomly
- struts2 学习笔记
- Android_程序未处理异常的捕获与处理
- POJ 3087 模拟+hash
- 阿里面试回来,想和Java程序员谈一谈
- 【noip2015】【DP】子串
- Yii2 - 03视图(View)操作,以及Layout的使用
- 静态链表的实现
- item点击回调封装(改变带来Position的参数)
- lintcode Max Points on a Line
- 使用Loader加载本地图片
- Java学习提要——对象序列化
- 读 《我的互联网方法论》 有感
- Ubuntu12.04(64bit)编译Android4.4源码和kernel