【经典动态规划问题】最长上升子序列 LIS

本文介绍了如何解决经典动态规划问题——最长上升子序列。通过O(N^2)的动态规划方法详细阐述了状态转移方程,并提及了O(N*logN)的解决方案,该方案结合贪心策略和二分查找,有效降低了时间复杂度。在O(N*logN)的方法中,利用有序的dp数组和lower_bound函数寻找插入位置,实现了更高效的求解过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

 

最长上升子序列:

O(N^2)动态规划:

O(N*logN):贪心+二分


最长上升子序列:

一个数的序列bi,当b1 < b2 < … < bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1, a2, …, aN),我们可以得到一些上升的子序列(ai1, ai2, …, aiK),这里1 <= i1 < i2 < … < iK <= N。

O(N^2)动态规划:

状态:dp[i],表示以A[i]为结尾数组的的最长上升子序列长度

初始化:A[i]的最长上升子序列最小为1,也就是左边的数都大于等于A[i],最长上升子序列只有A[i]元素本身,dp[i] = 1;

dp[i]表示以A[i]的最长子序列长度,我们现在找倒数第二个元素。

遍历A[0,...i-1],设其中小于A[i]的元素为A[k,j,z...],倒数第二个元素必定在A[k,j,z]中,dp[i]有几种可能:

 dp[i] = dp[k]+1;

dp[i ]= dp[j]+1;

dp[i] = dp[z]+1;

取这几种可能结果中的最大值,即为dp[i]的值。

最后返回的则是dp数组中的元素最大值。

class LongestIncreasingSubsequence {
public:
    int getLIS(vector<int> A, int n) {
        // write code here
        //dp[i]为A[0...i]中的最长上升子序列的长度
        int dp[501]= {0};
        for(int i = 0;i<n;i++){
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值