动态规划介绍
动态规划是比较重要的算法啦,打算慢慢写几篇博客总结一下。
动态规划的基本思想是:要求原问题的解,先求出更小一些的问题的解,由子问题的解通过某种方式得到原问题的解。
- 通常,我们也称每个子问题是一个状态,由子问题计算原问题,称为状态迁移
- 由子问题计算原问题的方式称为状态转移方程
- 一个动态规划算法的复杂度通常取决于状态的数量和状态迁移的复杂度
以上是有关动态规划的一些基本概念和概括。
LIS问题
第一篇就先讲一下最长递增子序列(LIS)的问题的解决。
给出一个数列A,求A的一个 长度最大的子数列B,使得B是一个递增数列
Example:
数列A: 5, 2, 8, 6, 3, 6, 9, 7
一个递增的子数列: 5, 8, 9
一个长度最大的递增子数列:2, 3, 6, 9
思路
将每一个数作为一个结点。从结点u到结点v连一条边,当且仅当u代表的数在原数列中出现在v代表的数前面,而且u代表的数比v代表的数小。这样转化保证了dag(有向无环图)的路径和原数列的递增子序列一一对应,因而dag上的最长路就是原数列的最长递增子序列。
代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int size, num;
cin >> size;
vector<int> nums;
for (int i = 0; i < size; i++) {
cin >> num;
nums.push_back(num);
}
vector<int> result;
result.assign(nums.size(), 1);
for (int i = 1; i < nums.size(); i++) {
int max = 0;
for (int j = 0; j < i; j