博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NOIp2015 子串
阅读量:4985 次
发布时间:2019-06-12

本文共 1416 字,大约阅读时间需要 4 分钟。


title: NOIp2016 子串

date: 2018-03-31 22:08:58
tags:
- DP
categories:
- 题解
- NOIp
- 2015
---

挺有意思的 DP

\(dp[i,j,k,l]\) 为字符串 A 的第 \(i\) 位匹配到了字符串 B 第 \(j\) 位,选出了 \(k\) 个子串,\(l\)\(0\) \(A_i\) 就不选。

然后转移就是比较明显的

\[ \begin{cases} dp[i,j,k,0] = dp[i-1,j,k,1] + dp[i-1,j,k,0] & anytime\\\ dp[i,j,k,1] = dp[i-1,j-1,k-1,1] + dp[i-1,j-1,k,1] + dp[i-1,j-1,k-1,0] & A_i=B_j \end{cases} \]
蛤?听说你想要开 \(1000∗200∗200∗2\) 的数组?

太 naive 辣!

可以发现,每次转移都只跟 \(dp[i-1]\) 有关系,所以只要使用滚动膜法数组就行啦!

#include 
#include
const int max_n = 1000 + 5;const int max_m = 200 + 5;const int mod = 1e9 + 7;int N, M, K;int Dp[2][max_m][max_m][2];char A[max_n], B[max_m];int main(){ scanf("%d %d %d", &N, &M, &K); scanf("%s", &A[1]); scanf("%s", &B[1]); Dp[0][0][0][0] = 1; for(int i = 1; i <= N; ++i) { int o = i & 1; Dp[o][0][0][0] = 1; for(int j = 1; j <= std::min(i, M); ++j) { for(int k = 1; k <= std::min(j, K); ++k) { int t = o ^ 1; Dp[o][j][k][0] = (Dp[t][j][k][0] + Dp[t][j][k][1]) % mod; if(A[i] == B[j]) Dp[o][j][k][1] = (((Dp[t][j - 1][k - 1][0] + Dp[t][j - 1][k - 1][1]) % mod ) + Dp[t][j - 1][k][1]) % mod; else Dp[o][j][k][1] = 0; } } } printf("%d\n", (Dp[N & 1][M][K][0] + Dp[N & 1][M][K][1]) % mod); return 0;}

转载于:https://www.cnblogs.com/zcdhj/p/8685677.html

你可能感兴趣的文章
自动化测试工具 Test Studio入门教程
查看>>
Python之进程线程
查看>>
排序算法(一) —— 冒泡排序
查看>>
No.026:Remove Duplicates from Sorted Array
查看>>
SpringBoot项目的几种创建方式,启动、和访问
查看>>
窗外【1】
查看>>
解决"disabled". Expected Boolean, got Number with value 0
查看>>
Android 四大组件之Service
查看>>
OC--init,initialize,initWithCoder:,initWithFrame:各方法的区别和加载顺序
查看>>
xml.dom.minidom
查看>>
Exponentiation
查看>>
本地jar上传到本地仓库
查看>>
四则运算C++带Qt界面版本,吾王镇楼。。。。。
查看>>
各种获取时间的方法包含各类时间格式
查看>>
安卓7.0手机拍照闪退问题解决
查看>>
黑马程序员------IO(一)
查看>>
springcloud的配置
查看>>
ME525+ Defy+ 刷机指南[zz]
查看>>
支持触屏的jQuery轮播图插件
查看>>
差一点搞混了Transactional注解
查看>>