NVIDIA RTX wallpaper
583 字
3 分钟
【OI考古】动态规划 | 动态规划基础
动态规划(Dynamic programming,简称 DP)是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。
动态规划常常适用于有重叠子问题和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法。
最长上升子序列(LIS)
给出一个序列 ,求其最长不下降(或上升)子序列。
求最长上升子序列(LIS)的算法是Yukko介绍给我的第一个算法。
解决方案( )
状态设计:
表示以第 个数结尾的最长上升子序列的最长长度。
状态转移方程:
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 100500;
int n, ans;
int a[maxn], dp[maxn];
int main()
{
scanf("%d", &n);
for(int i=1; i<=n; i++)
{
scanf("%d", &a[i]);
dp[i] = 1;
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j < i; j++)
{
if (a[i] > a[j] && dp[i] < dp[j] + 1) //如果a[i] > a[j],则a[i]可以接在以a[j]结尾的上升子序列后面
dp[i] = dp[j] + 1; //如果dp[i] < dp[j] + 1,则可以用dp[j] + 1来更新dp[i]
}
ans = max(ans, dp[i]); //取dp[i]的最大值来作为ans
}
printf("%d", ans);
return 0;
}
解决方案( )
例题
最长公共子序列(LCS)
模板题:洛谷 P1439 | [模板]最长公共子序列
题目描述
给出 的两个排列 和 ,求它们的最长公共子序列。
输入格式
第一行是一个数 。
接下来两行,每行为 个数,为自然数 的一个排列。
输出格式
一个数,即最长公共子序列的长度。
输入输出样例
输入 #1
5
3 2 1 4 5
1 2 3 4 5
输出 #1
3
数据规模与约定
- 对于 的数据, ;
- 对于 的数据, 。
解决方案
状态设计:
表示 前 位, 前 位的最长公共子序列长度。
状态转移方程:
请参阅
【OI考古】动态规划 | 动态规划基础
https://blog.vonbrank.com/posts/oi-dp-basic-dp-algorithm/