673.最长递增子序列

673.最长递增子序列

思路:动态规划

dp[i]表示nums[i]时最长递增子序列的长度

初始状态dp[0]=0;用一个j去遍历以nums[i]之前所有子序列的起点

cnt[i]记录对应dp下最长子序列的个数

状态转移方程:

(1)如果nums[j] >= nums[i] ,非递增 不考虑

(2)如果nums[j] < nums[i],此时是递增,那么到 i 最长的子序列= 到 j 最长的子序列 + nums[i] ,dp[i] = dp[j] + 1

对于cnt和maxL的维护

(1)dp[i] > dp[j] + 1时,maxL不变

(2)dp[i] = dp[j] + 1时,maxL相等,且出现长度相同的不同最长子序列,此时cnt需要改变

(3)dp[i] < dp[j] + 1,maxL需要更新变为dp[j] + 1,cnt要重置到新的cnt[j]

cnt[j]的含义为以j做结尾的最长递增子序列个数,

如果cnt[j]=2,再加一个新的nums[i]加入递增子序列,那么cnt[i]的个数是cnt[j]+1,即3

那么在情况(2)中对cnt的维护:遍历j时,有不同的j结尾的子序列新增nums[i]后最大长度相同,那么需要现有的cnt[i]+cnt[j](实际上相当于所有能和nuns[i]组成最长递增子序列的cnt[j]的和,起一个累加效果)

最后再设置一个maxL置,不断比较每一个dp[i],

(1)maxL<dp[i],更新maxL=dp[i]并重新计数,res=cnt[i]

(2)maxL==dp[i],cnt需要累加,res=res+cnt[i];

(2)maxL>dp[i],无意义

代码:

cpp 复制代码
class Solution {
public:
    int findNumberOfLIS(vector<int>& nums) {
        int n=nums.size();
        //初始化为1,至少单个字符可以当作子序列
        vector<int>dp(n,1);
        vector<int>cnt(n,1);
        int counter=1;
        int maxL=1;
        int res=0;
        for(int i=0;i<n;i++){
           for(int j=0;j<i;j++){
              //递增
              if(nums[i]>nums[j]){
                  //对cnt进行计算
                  if(dp[i]<dp[j]+1){ //最大值变化
                      dp[i]=dp[j]+1;
                      //重置cnt,到j结尾的最大子序列也可能有多个,所以不是重置到1
                      cnt[i]=cnt[j];

                  }else if(dp[i]==dp[j]+1){//最大值相同的多一个
                      //cnt+1
                      cnt[i]=cnt[i]+cnt[j];
                  }
              }
           }
            if(dp[i]>maxL){
                maxL=dp[i];
                res=cnt[i];
            }else if(dp[i]==maxL){
                res=res+cnt[i];
            }
        }
        return res;
    }
};
相关推荐
南境十里·墨染春水11 分钟前
C++传记(面向对象)虚析构函数 纯虚函数 抽象类 final、override关键字
开发语言·c++·笔记·算法
2301_7971727520 分钟前
基于C++的游戏引擎开发
开发语言·c++·算法
有为少年1 小时前
告别“唯语料论”:用合成抽象数据为大模型开智
人工智能·深度学习·神经网络·算法·机器学习·大模型·预训练
比昨天多敲两行1 小时前
C++ 二叉搜索树
开发语言·c++·算法
Season4501 小时前
C++11之正则表达式使用指南--[正则表达式介绍]|[regex的常用函数等介绍]
c++·算法·正则表达式
Tisfy2 小时前
LeetCode 2839.判断通过操作能否让字符串相等 I:if-else(两两判断)
算法·leetcode·字符串·题解
问好眼2 小时前
《算法竞赛进阶指南》0x04 二分-1.最佳牛围栏
数据结构·c++·算法·二分·信息学奥赛
会编程的土豆2 小时前
【数据结构与算法】优先队列
数据结构·算法
minji...4 小时前
Linux 进程信号(二)信号的保存,sigset_t,sigprocmask,sigpending
linux·运维·服务器·网络·数据结构·c++·算法
罗湖老棍子4 小时前
最大数(信息学奥赛一本通- P1549)(洛谷-P1198)
数据结构·算法·线段树·单点修改 区间求最大值