题目:从一个由N个整数排列组成的整数序列中,自左向右不连续的选出一组整数,可以组成一个单调减小的子序列(如从{68 69 54 64 68 64 70 67 78 62 98 87}中我们可以选取出{69 68 64 62}这个子序列;当然,这里还有很多其他符合条件的子序列)。给定整数序列的长度和整数序列中依次的值,请你求出这个整数序列中“最长的单调减小的子序列的长度”以及“不同但长度都是最长得单调减小的子序列的数量”。

输入第1行为一个整数N,表示输入的整数序列的长度(1≤N≤50000)。输入第2行包括由空格分隔的N个整数(每个整数都在32位长整型范围内)。

输出包括一行,为两个数字,分别为针对给定的整数序列求出的“最长的单调减小的子序列的长度”以及“值不同但长度都是最长得单调减小的子序列的数量”

样例输入

12

68 69 54 64 68 64 70 67 78 62 98 87

样例输出

4 2

对于这个题,一共有两个小部分的问题要解决。前一个问题是最长不上升子序列,属于LIS问题,使用动态规划解决,后一个问题属于去重问题。

对于LIS问题,声明dp[i] 以第i个元素为结尾的子序列的最长的长度。

对第i个元素,与前i-1个元素进行比较:

dp[i] = 1; //当末尾只要一个元素时 长度为1

如果 arr[i] < arr[j]:

如果dp[i] < dp[j] + 1

此时dp[i]的值会被更新为dp[j] + 1

其他情况不做处理

对于去重问题:

“值不同但长度都是最长得单调减小的子序列的数量” 这里说的是:

比如输入:

6

2 1 2 1 2 1

输出应为 2 1

2 1 2 1 这两个是值相同的,所以应该当做一个

使用size[i] 数组去记录第i元素为结尾时,值不同但长度都是最长得单调减小的子序列的数量

每次在dp更新一遍以后,进行size的更新。

去掉相同值的情况,如果只去关注最后结尾时:

因为每次遍历都会更新状态,也就是说如果有相同值的时候 后者会把前者的情况 都会过一遍,所以只要每次更新时保证只取相同值的最后一个出现的元素位置的size[j]即可,也就是最右边的那个。

对于i元素所构成的最长子序列的前一个元素可能有很多不同值,所以要记录这些值,并只取最右边的。

最后size 和 dp都已经生成了最终数组

然后对整个数组进行遍历, 找出最大序列 且值不同的序列的数量

方法同找单个i位置元素的值不同但长度都是最长得单调减小的子序列的数量 一致

其他说明:

数据较大 使用java中的BigInteger

遍历找值不同但长度都是最长得单调减小的子序列的数量时 使用倒序查找

代码:

Scanner read = new Scanner(System.in);

int n = read.nextInt();

long[] arr = new long[n];

long[] dp = new long[n];

BigInteger[] size = new BigInteger[n];

for(int i = 0; i < n; ++i){

arr[i] = read.nextLong();

}

long max = 0;

for(int i = 0; i < n; ++i){

dp[i] = 1;

size[i] = new BigInteger("0");

for(int j = 0; j < i; ++j){

if(arr[j] > arr[i]){

if(dp[j] + 1 > dp[i]){

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

}

}

}

if(dp[i] > max){

//更新 最长长度

max = dp[i];

}

// 确定以arr[i]结尾的 子序列中 值不同但长度都是最长得单调减小的子序列的数量

if(dp[i] > 1){//如果 不是只有一个数字的时候

Set sl = new HashSet<>();

for(int j = i - 1; j >= 0; --j){

//从右向左查询 只查询第一次遇到的并且是最大长度的 size[i]

// 没有记录路径 通过 arr[j] > arr[i] && dp[j] == dp[i] - 1 来确定是否是前一个转移

// 遇到相同结尾的情况,更右边的已经包含了左边的情况

if(arr[j] > arr[i] && dp[j] == dp[i] - 1 && !sl.contains(arr[j])){

sl.add(arr[j]);//去重

size[i] = size[i].add(size[j]);

}

}

}else{

//只有一个数字是 数量为1

size[i] = new BigInteger("1");

}

}

BigInteger maxBigI = new BigInteger("0");

Set set = new HashSet<>();

//遍历整个序列 找出最大长度 且值不同的序列的数量

for(int i = n - 1; i >= 0; --i){

if(dp[i] == max && !set.contains(arr[i])){

set.add(arr[i]);

maxBigI = maxBigI.add(size[i]);

}

}

System.out.println(max + " " + maxBigI.toString());

}

求最长单调子序列java,单调减子序列(java实现)相关推荐

  1. JAVA单字节读取,java资料读取。(单字节读取和按行读取读取)

    当前位置:我的异常网» 编程 » java资料读取.(单字节读取和按行读取读取) java资料读取.(单字节读取和按行读取读取) www.myexceptions.net  网友分享于:2013-12 ...

  2. leetcode 792. Number of Matching Subsequences | 792. 匹配子序列的单词数(Java)

    题目 https://leetcode.com/problems/number-of-matching-subsequences/ 题解 一看数据规模,普通暴力解法肯定超时了.想了半天怎么用 Trie ...

  3. java单链表_(java实现)单链表

    什么是单链表 在了解单链表之前,你知道什么是链表吗?如果你不知道什么是链表,可以看看我的这篇博客 单链表是链表的其中一种基本结构.一个最简单的结点结构如图所示,它是构成单链表的基本结点结构.在结点中数 ...

  4. java 单例 构造函数,Java单例模式学习

    1.单例模式要点及实现角度 要点:一是某个类只能有一个实例: 二是它必须自行创建这个实例: 三是它必须自行向整个系统提供这个实例. 从具体实现角度来说,就是以下三点: 一是单例模式的类只提供私有的构造 ...

  5. java 单例方法,java单例模式使用及注意事项

    1. 说明 1)单例模式:确保一个类只有一个实例,自行实例化并向系统提供这个实例 2)单例模式分类:饿单例模式(类加载时实例化一个对象给自己的引用),懒单例模式(调用取得实例的方法如getInstan ...

  6. java单分支结构,java基础语法分支结构

    java分支结构有两种: 1,if语句, 2,switch语句 if语句 格式一: if(条件表达式){ ​ 执行代码块; } [当条件表达式的结果为true时,执行代码块] 例: if(11> ...

  7. java 单例继承,Java单例模式的讲解

    1,单例模式的要素 1)私有构造方法. 2)public static synchronized的getInstance()方法. 上述2个要素虽然可以保证单例模式的实现,但并不是最好的方式.因为当我 ...

  8. 最长单调递增子序列 动态规划 (java)

    题目描述: 设计一个O(N^2)算法,找出n个数据组成的序列的最长单调递增子序列. 输入示例: 8 1 2 3 -9 3 9 0 11 输出示例: 5 1 2 3 9 11 设计思路: 有一个数组 a ...

  9. 【训练题】航线设计(优化求较大数据规模的最长单调子序列)

    [问题描述] 有一个国家被一条河划分为南北两部分,在南岸和北岸总共有N对城镇,每一城镇在对岸都有唯一的友好城镇.任何两个城镇都没有相同的友好城镇.每一对友好城镇都希望有一条航线来往.于是他们向政府提出 ...

最新文章

  1. 商汤IPO首日市值涨百亿,徐立感慨时代之幸:有机会改变世界!
  2. Flex与.NET互操作(九):FluorineFx.NET的认证(Authentication )与授权(Authorization)
  3. 如何考虑程序的优化性
  4. 20.QT-Qpixmap实现图片鼠标缩放,鼠标拖动示例(详解)
  5. url参数拼接 php,js URL参数的拼接方法比较_javascript技巧
  6. linux 安装校园客户端,Ubuntu Linux环境下校园网客户端安装使用
  7. win10程序员软件列表(持续更新中...)
  8. pdfbox / XSL + FOP 转换 PDF文档
  9. Linux tcp拥塞控制
  10. Altium Designer PCB与SCH参照布局
  11. 手机盾验证失败是什么意思_腾讯手机安全验证失败怎么回事
  12. 一个屌丝程序员的青春(一一零)
  13. 吴恩达的2022年终盘点:生成式AI、ViT、大模型
  14. 面试 java -----Socket编程
  15. 华师计算机在线作业答案,2016春季华师计算机基础在线作业答案
  16. SAP Router是个啥
  17. 恢复服务器安装信息被破坏了,服务器存储瘫痪数据恢复成功案例-服务器数据恢复...
  18. 发票 税率 普票 增值税发票
  19. C语言以延时的状态读取数据文件,CH376 U盘文件读写相关C语言代码
  20. 【Vue】快乐学习第四篇,组件访问及插槽使用

热门文章

  1. Xamarin开发笔记—百度在线语音合成
  2. IMP-00002: 无法打开 D:\orcldat\test_20111024.dmp 进行读取,rman备份
  3. 任何项目都适用的CMakeLists配置
  4. 计算机应用基础第二章,计算机应用基础第二章上机操作题
  5. docker+mysql创建用户名密码_docker构建私有仓库并设置仓库用户和密码
  6. java appender_log4j的Appenders配置方法
  7. adaptivitypara设置选0还是1_喝牛奶,选全脂还是低脂?家里人能不能喝同1种牛奶?...
  8. vip会员管理系统c语言,路西牌会员管理系统。
  9. python函数式编程读取数据时出现错误_Python编程中,函数遇到问题是抛出错误好还是约定返回值好?...
  10. python读取数据库数据类型_Python实现从SQL型数据库读写dataframe型数据的方法【基于pandas】...