Noip2015 子串 【动态规划】
来源:互联网 发布:原声电影翻译软件 编辑:程序博客网 时间:2024/06/05 13:29
这道题思维量是可以的=。=
学习了dalao们的状态设计,觉得自己还是差很多啊!
先说一个没有滚动数组的版本
对于A串的一个字符,只有选和不选两种可能,选是一种方案,不选也是一种方案
设
还需要加上A串第i项不选择的方案
设
那么
整个过程就是用A串的每一个字符都去试试匹配B串的前j个字符,一直到 j = m,这时B串已经被完全匹配,然后用下一个字符再去匹配,最后把A中的每一个字符都试一遍
关于s的转移:
这个转移也可以用阶段的方式来理解,s就是上一阶段(A试用第i-1个字符)时的方案总数加上A试用第i个字符时的方案总数
现在关键是求出f的转移
当A[i]==B[j]
时,i字符是可选的,i字符可以和i-1字符组成一个子串,也可以自立门户,单独成为一个新串
1.和i-1组成一个子串,由
2.不和i-1组成一个子串,由
关于第二个转移,首先自立门户的话,子串数量加1,而状态定义为选择了第i个字符并且现在是第k个子串,那么i的方案数一定是由k-1号子串转移而来的
当A[i]!=B[j]
时,第i号字符显然是不可选的,所以
总状态转移方程:
代码(未优化空间,70分做法)
#include <cstdio>#include <iostream>#include <cstring>#include <string>#define moder 1000000007using namespace std;char a[1010],b[210];int f[1010][210][210],s[1010][210][210],n,m,kk;int main() { cin >> n >> m >> kk; cin >> a+1 >> b+1; s[0][0][0] = 1; for(int i=1; i<=n; i++) { s[i][0][0] = 1; for(int j=1; j<=m; j++) { for(int k=1; k<=min(kk,j); k++) { if(a[i] == b[j]) { f[i][j][k] = (f[i-1][j-1][k] + s[i-1][j-1][k-1]) % moder; s[i][j][k] = (s[i-1][j][k] + f[i][j][k]) % moder; } else { s[i][j][k] = s[i-1][j][k]; } } } } cout << s[n][m][kk]; return 0;}
现在就应该开始滚动数组啦
可以看出,状态之间的转移只是i-1到i的转移,所以可以压掉i维,并且对j和k进行逆序枚举(每个字符只能选一次)
代码:
#include <cstdio>#include <iostream>#include <cstring>#include <string>#define moder 1000000007using namespace std;char a[1010],b[210];int f[210][210],s[210][210],n,m,K;int main() { scanf("%d %d %d",&n,&m,&K); scanf("%s %s",a+1, b+1); s[0][0] = 1; for(int i=1; i<=n; i++) { for(int j=m; j>=1; j--) { for(int k=min(K,j); k>=1; k--) { if(a[i] == b[j]) { f[j][k] = (f[j-1][k] + s[j-1][k-1]) % moder; s[j][k] = (s[j][k] + f[j][k]) % moder; } else { f[j][k] = 0;//这是必要的,即使不更新i,这个数组也会保存着i-1的值 } } } } printf("%d",s[m][K]); return 0;}
- Noip2015 子串 【动态规划】
- NOIP2015 子串 【动态规划】
- 【NOIP2015提高组T5】子串-字符串上的动态规划
- 【NOIP2015】子串
- NOIP2015 day2t2 子串
- 【NOIP2015】子串
- NOIP2015 子串
- 【noip2015】【DP】子串
- NOIP2015 子串 DP
- NOIP2015子串
- noip2015 子串 dp
- NOIP2015子串
- NOIP2015 day2t2 子串
- NOIP2015 子串 dp
- [NOIP2015]Day2T2 子串
- NOIP2015子串题解
- luogu2679 noip2015 子串
- 【NOIP2015】子串
- String equals方法和==的区别
- [翻译]MapReduce: Simplified Data Processing on Large Clusters
- 树- path sum
- 凯哥
- MFC之ODBC实现对Excel文件读写
- Noip2015 子串 【动态规划】
- 我们的敏捷之路——计划会议篇
- Linux 常用命令
- (VC++)cl/nmake编译器系统环境变量配置
- JS垃圾回收机制
- Hibernate中的事务
- 2017年6月1日由新浪博客搬家至此
- Day2/margin-right/ease(in&out)/eq selector/fadeIn()/fadeOut()/insert Sorting
- 怎样防止头文件被重复引用