当前位置: 首页 > news >正文

关于线性DP模板

关于线性DP模板

线性DP是动态规划中最简单的一种,刚入门从这些模板中学习一下。


数字三角形

来源:数字三角形 - OpenJ_Bailian 2760 - Virtual Judge

思路

  • DP递推一定是从最开始推到最终的状态
  • 路径的尽头一定是三角形最上方,我们从最下面开始递推
  • 每次取较大的那个相加,使得本步骤最优:f[i][j]=max(f[i+1][j],f[i+1][j+1])f[i][j]=max(f[i+1][j],f[i+1][j+1])f[i][j]=max(f[i+1][j],f[i+1][j+1])

代码

void solve()
{cin >> n;for(int i=1; i<=n; i++)for(int j=1; j<=i; j++)cin >> a[i][j];for(int i=n-1; i>=1; i--){for(int j=1; j<=i; j++)a[i][j]+=max(a[i+1][j],a[i+1][j+1]);}cout << a[1][1];
}

最长上升子序列

来源:B3637 最长上升子序列 - 洛谷

思路

  • 当遇到比当前序列都大的元素时将其添加到末尾
  • 如果不是就替换第一个大于等于它的元素,这样不会改变原有的长度并使整个序列尽量小,加入更多元素

代码

void solve()
{cin >> n;for(int i=1; i<=n; i++) cin >> a[i];int len=0;for(int i=1; i<=n; i++){int pos=lower_bound(b+1,b+len+1,a[i])-b;if(pos>len) b[++len]=a[i];else b[pos]=a[i];}cout << len;
}

最长公共子序列1(求长度)

来源:最长公共子序列(Longest Common Subsequence,LCS) - 洛谷 U165581 - Virtual Judge

思路

  • 如果此时不匹配的话那就不能选,继承上一轮的状态或者左边的状态: f[i][j]=max(f[i−1][j],f[i][j−1])f[i][j]=max(f[i-1][j],f[i][j-1])f[i][j]=max(f[i1][j],f[i][j1])
  • 如果此时匹配那么就是上一轮没选它时的状态再选上它:f[i][j]=f[i−1][j−1]+1f[i][j]=f[i-1][j-1]+1f[i][j]=f[i1][j1]+1

过程演示:

i\jBDCAB
A“”“”“”“A”“A”
B“B”“B”“B”“B”“AB”
C“B”“B”“BC”“BC”“BC”
B“B”“B”“BC”“BC”“BCB”
D“B”“BD”“BD”“BD”“BDB”
A“B”“BD”“BD”“BDA”“BDB”
B“B”“BD”“BD”“BDA”“BDAB”

代码

int f[N][N];
void solve()
{cin >> a >> b;a=' '+a,b=' '+b;for(int i=1; i<a.size(); i++)for(int j=1; j<b.size(); j++)if(a[i]==b[j])f[i][j]=f[i-1][j-1]+1;elsef[i][j]=max(f[i][j-1],f[i-1][j]);size_t s1=a.size();size_t s2=b.size();cout << f[s1-1][s2-1];return;
}

一维优化

  • 由于二维数组非常的浪费,效率极其有限,所以我们可以像背包问题那样将其压缩成一维

  • 由刚刚的分析可知:此时的状态只和当前轮和前一轮的状态有关,所以我们用一个p数组表示前一轮的状态就行

  • p[j]=f[i−1][j]p[j]=f[i-1][j]p[j]=f[i1][j]

int f[N],p[N];
void solve()
{cin >> a >> b;a=' '+a,b=' '+b;for(int i=1; i<a.size(); i++){for(int j=1; j<b.size(); j++){if(a[i]==b[j])f[j]=p[j-1]+1;elsef[j]=max(f[j-1],p[j]);}for(int j=0; j<=b.size(); j++) p[j]=f[j];//复制当轮状态}size_t s2=b.size();cout << f[s2-1];
}

最长公共子序列2(求子串)

来源:最长公共子序列Lcs - 51Nod 1006 - Virtual Judge

类似的,这个只是让求了长度,如果要求具体的子串呢?其实是一样的,可以再练练手

void solve()
{string a,b;cin >> a >> b;n=a.size(),m=b.size();a=' '+a,b=' '+b;for(int j=0;j<=m;j++) p[j]=f[j]="";for(int i=1; i<=n; i++){for(int j=1; j<=m; j++){if(a[i]!=b[j]){if(f[j-1].size()>p[j].size())f[j]=f[j-1];else f[j]=p[j];}else f[j] = p[j-1] + a[i];}for(int j=0;j<=m;j++) p[j]=f[j];}cout << f[m];
}

最长公共子序列3(数字)

来源:P1439 【模板】最长公共子序列 - 洛谷

思路

  • 重要的不是重复,而是相对位置
  • 将第一个数组的元素下标映射到第二个数组,这样就得到了它们在下面的相对位置
  • 由于最长公共子序列只能是从左往右不能回来,所以用LIS对下标进行处理

代码

void solve()
{cin >> n;map<int,int> mp;for(int i=1; i<=n; i++){cin >> x;mp[x]=i;}for(int i=1; i<=n; i++){cin >> x;a[i]=mp[x];}int len=0;for(int i=1; i<=n; i++){int pos=lower_bound(b+1,b+len+1,a[i])-b;if(pos>len) b[++len]=a[i];else b[pos]=a[i];}cout << len;
}

编辑距离

来源:P2758 编辑距离 - 洛谷

思路

  • f[i][j]f[i][j]f[i][j]含义:将a前i个字符改为b前j个字符所需要的次数
  • 初始化:将b无字符时转换成a前i字符需i次,下面同理
  • 由于f数组将a与b的状态融为一体,不用考虑删减只用考虑增加
  • 如果a[i]==b[j]a[i]==b[j]a[i]==b[j]则不用修改
  • 若要修改就要探讨是否要增加、替换谁所用更少

代码

int f[N][N];//将a前i个字符改为b前j个字符所需要的次数
void solve()
{string a,b;cin >> a >> b;n=a.size(),m=b.size();a=' '+a,b=' '+b;for(int i=0; i<=n; i++) f[i][0]=i;//将b无字符转换成a前i字符需i次for(int j=0; j<=m; j++) f[0][j]=j;for(int i=1; i<=n; i++){for(int j=1; j<=m; j++){int k=1;if(a[i]==b[j]) k=0;//以谁为基准替换        还是增加f[i][j]=min(min(f[i-1][j]+1,f[i][j-1]+1),f[i-1][j-1]+k);}}cout << f[n][m];
}
http://www.dtcms.com/a/326313.html

相关文章:

  • 《汇编语言:基于X86处理器》第13章 高级语言接口(1)
  • [Ubuntu] xrdp共享连接 Ubuntu 屏幕 | xfce4
  • 建筑兔零基础python自学记录119|数据处理(4)-23
  • 需求列表如何做层级结构
  • Redis类型之Hash
  • 重学前端009 --- 响应式网页设计 CSS 伪选择器
  • 订单簿价格冲击模型与机器学习在大单策略中的融合
  • 元数据管理与数据治理平台:Apache Atlas 基本搜索 Basic Search
  • Apache Ignite分片线程池:高并发保序新方案
  • MCU 软件断点注意事项!!!
  • 【数据结构入门】树
  • 基于Go-Zero框架实现的小demo
  • 爬虫和数据分析相结合案例
  • 软件开发:一场精密的生命构建
  • 疯狂星期四文案网第36天运营日记
  • jsdiff + diff2html【jQuery】实现文件对比功能
  • Linux DNS服务解析原理与搭建
  • ResponseBodyAdvice是什么?
  • 基于动态顺序表实现【通讯录系统】:有文件操作部分哦!
  • Oracle主从incarnation不一致问题解决
  • ComfyUI安装
  • 【96页PPT】华为IPD流程管理详细版(附下载方式)
  • 强化学习常用数据集
  • HBase BlockCache:LRU Cache
  • Qt界面优化
  • TD-IDF的一些应用
  • 降压型DCDC电源芯片推荐-芯伯乐XBL4001 40V/5A
  • Python3.10 + Firecrawl 下载 Markdown 文档:构建高效通用文章爬虫
  • 深度学习 --- 迁移学习以及onnx推理
  • 自建Web应用防火墙(WAF)