最长递增子序列的个数

给定一个未排序的整数数组,找到最长递增子序列的个数。

示例 1:

输入: [1,3,5,4,7]
输出: 2
解释: 有两个最长递增子序列,分别是 [1, 3, 4, 7] 和[1, 3, 5, 7]。
示例 2:

输入: [2,2,2,2,2]
输出: 5
解释: 最长递增子序列的长度是1,并且存在5个子序列的长度为1,因此输出5。

思路:

思路
我们需要定义两个vector数组:

vector<int> dp(n,1): 表示以nums[i]结尾的LIS长度
vector<int> count(n,1): 表示以nums[i]结尾的LIS的组合的个数
这里两个数组全部初始化为1,显然当序列长度为1时,LIS的长度为1,并且所有LIS的个数至少为1(不可能为零)

两重循环遍历

第一重用i扫描(1 <= i < nums.size())
第二重用j扫描(0 <= j < i)
显然 j 永远小于 i

若要LIS成立,我们只要考虑nums[j] < nums[i]的情况,其他情况则不考虑

(1)当dp[j]+1 > dp[i]时,意味着我们第一次找到这个组合
(2)当dp[j]+1 == dp[i]时,意味着我们不是第一次找到这个组合

当我们遇到情况(1)时(dp[j]+1 > dp[i]),只需要将LIS的长度加一,并且将组合数设为与nums[j]一样即可

当我们遇到情况(2)时(dp[j]+1 == dp[i]),只需要将nums[j]的组合数添加上去即可

注意以上两种情况都是基于(nums[j] < nums[i])

最后我们返回所有LIS的所有组合数

class Solution {
public:
int findNumberOfLIS(vector<int>& nums) {
int n = nums.size();
if(n<=0) return n;
vector<int> dp(n, 1);
vector<int> count(n,1); for(int i=1; i<n; i++) {
for(int j=0; j<i; j++) {
if(nums[j] < nums[i]) {
// 第一次找到
if(dp[j]+1 > dp[i]) {
dp[i] = dp[j] + 1;
count[i] = count[j];
// 再次找到
} else if(dp[j]+1 == dp[i]) {
count[i] += count[j];
}
}
}
}
// 最后的返回值应该是所有最大长度的所有count的总和
int max = *max_element(dp.begin(), dp.end());
int res = 0;
for(int i=0; i<n; i++) {
if(dp[i] == max)
res += count[i];
} return res; }
};

动态规划精讲(一)LC 最长递增子序列的个数的更多相关文章

  1. [Swift]LeetCode673. 最长递增子序列的个数 | Number of Longest Increasing Subsequence

    Given an unsorted array of integers, find the number of longest increasing subsequence. Example 1: I ...

  2. Q673 最长递增子序列的个数

    给定一个未排序的整数数组,找到最长递增子序列的个数. 示例 1: 输入: [1,3,5,4,7] 输出: 2 解释: 有两个最长递增子序列,分别是 [1, 3, 4, 7] 和[1, 3, 5, 7] ...

  3. Leetcode 673.最长递增子序列的个数

    最长递增子序列的个数 给定一个未排序的整数数组,找到最长递增子序列的个数. 示例 1: 输入: [1,3,5,4,7] 输出: 2 解释: 有两个最长递增子序列,分别是 [1, 3, 4, 7] 和[ ...

  4. Java实现 LeetCode 673 最长递增子序列的个数(递推)

    673. 最长递增子序列的个数 给定一个未排序的整数数组,找到最长递增子序列的个数. 示例 1: 输入: [1,3,5,4,7] 输出: 2 解释: 有两个最长递增子序列,分别是 [1, 3, 4, ...

  5. 51Nod:1134 最长递增子序列

    动态规划 修改隐藏话题 1134 最长递增子序列  基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 给出长度为N的数组,找出这个数组的最长递增子序列.(递 ...

  6. 动态规划 - 最长递增子序列(LIS)

    最长递增子序列是动态规划中经典的问题,详细如下: 在一个已知的序列{a1,a2,...,an}中,取出若干数组组成新的序列{ai1,ai2,...,aim},其中下标i1,i2,...,im保持递增, ...

  7. 【动态规划】拦截导弹_dilworth定理_最长递增子序列

    问题 K: [动态规划]拦截导弹 时间限制: 1 Sec  内存限制: 256 MB提交: 39  解决: 10[提交][状态][讨论版] 题目描述 张琪曼:“老师,修罗场是什么?” 墨老师:“修罗是 ...

  8. 动态规划----最长递增子序列问题(LIS)

    题目: 输出最长递增子序列的长度,如输入 4 2 3 1 5 6,输出 4 (因为 2 3 5 6组成了最长递增子序列). 暴力破解法:这种方法很简单,两层for循环搞定,时间复杂度是O(N2). 动 ...

  9. 算法之动态规划(最长递增子序列——LIS)

    最长递增子序列是动态规划中最经典的问题之一,我们从讨论这个问题开始,循序渐进的了解动态规划的相关知识要点. 在一个已知的序列 {a1, a 2,...an}中,取出若干数组成新的序列{ai1, ai ...

随机推荐

  1. Spring Security中实现微信网页授权

    微信公众号提供了微信支付.微信优惠券.微信H5红包.微信红包封面等等促销工具来帮助我们的应用拉新保活.但是这些福利要想正确地发放到用户的手里就必须拿到用户特定的(微信应用)微信标识openid甚至是用 ...

  2. pikachu 不安全的url跳转

    不安全的url跳转问题可能发生在一切执行了url地址跳转的地方.如果后端采用了前端传进来的(可能是用户传参,或者之前预埋在前端页面的url地址)参数作为了跳转的目的地,而又没有做判断的话就可能发生&q ...

  3. pikachu CSRF

    CSRF简介 CSRF 是 Cross Site Request Forgery 的 简称,中文名为跨域请求伪造在CSRF的攻击场景中,攻击者会伪造一个请求(一般是一个链接)然后欺骗目标用户进行点击, ...

  4. python初始化定义空变量-小记

    python初始化定义空变量 数值 digital_value = 0 字符串 str_value = "" 列表 list_value = [] 字典 ditc_value = ...

  5. 线程 Thread类 GIL锁 信号量 Event事件

    线程的开启方法 进程是操作系统调度的最小单位,一个进程最少有一个主线程,而一个进程中可以开启多个线程 from threading import Thread def task(): print('A ...

  6. 1、Task的优势

    1.Task的优势 ThreadPool相比Thread来说具备了很多优势,但是ThreadPool却又存在一些使用上的不方便.比如: ◆ ThreadPool不支持线程的取消.完成.失败通知等交互性 ...

  7. .Net 5 新特性之--支持字典在迭代中进行修改

    我们都知道以前字典迭代中是不支持动态修改的[否则会报错::"Collection was modified; enumeration operation may not execute.&q ...

  8. javacc在stanfordnlp中的应用

    总结: 这个javacc感觉比较复杂,在于stanfordnlp中 p.p1 { margin: 0; font: 11px Monaco } CoreMapExpressionExtractor这个 ...

  9. mzy,struts学习(三):action中获得servlet中三域一参的三种方法

    package com.mzy.servlet; import java.util.Arrays; import java.util.Map; import javax.servlet.Servlet ...

  10. BST B树 B+树

    二叉排序树/二叉搜索树 (BST) 定义 左子树节点值<根节点值<右子树节点值 默认不允许两个节点的关键值相同 进行中序遍历可以得到递增的有序序列 查找效率 取决与树的高度,最好O(log ...