求最长单调子序列java,单调减子序列(java实现)
题目:从一个由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实现)相关推荐
- JAVA单字节读取,java资料读取。(单字节读取和按行读取读取)
当前位置:我的异常网» 编程 » java资料读取.(单字节读取和按行读取读取) java资料读取.(单字节读取和按行读取读取) www.myexceptions.net 网友分享于:2013-12 ...
- leetcode 792. Number of Matching Subsequences | 792. 匹配子序列的单词数(Java)
题目 https://leetcode.com/problems/number-of-matching-subsequences/ 题解 一看数据规模,普通暴力解法肯定超时了.想了半天怎么用 Trie ...
- java单链表_(java实现)单链表
什么是单链表 在了解单链表之前,你知道什么是链表吗?如果你不知道什么是链表,可以看看我的这篇博客 单链表是链表的其中一种基本结构.一个最简单的结点结构如图所示,它是构成单链表的基本结点结构.在结点中数 ...
- java 单例 构造函数,Java单例模式学习
1.单例模式要点及实现角度 要点:一是某个类只能有一个实例: 二是它必须自行创建这个实例: 三是它必须自行向整个系统提供这个实例. 从具体实现角度来说,就是以下三点: 一是单例模式的类只提供私有的构造 ...
- java 单例方法,java单例模式使用及注意事项
1. 说明 1)单例模式:确保一个类只有一个实例,自行实例化并向系统提供这个实例 2)单例模式分类:饿单例模式(类加载时实例化一个对象给自己的引用),懒单例模式(调用取得实例的方法如getInstan ...
- java单分支结构,java基础语法分支结构
java分支结构有两种: 1,if语句, 2,switch语句 if语句 格式一: if(条件表达式){ 执行代码块; } [当条件表达式的结果为true时,执行代码块] 例: if(11> ...
- java 单例继承,Java单例模式的讲解
1,单例模式的要素 1)私有构造方法. 2)public static synchronized的getInstance()方法. 上述2个要素虽然可以保证单例模式的实现,但并不是最好的方式.因为当我 ...
- 最长单调递增子序列 动态规划 (java)
题目描述: 设计一个O(N^2)算法,找出n个数据组成的序列的最长单调递增子序列. 输入示例: 8 1 2 3 -9 3 9 0 11 输出示例: 5 1 2 3 9 11 设计思路: 有一个数组 a ...
- 【训练题】航线设计(优化求较大数据规模的最长单调子序列)
[问题描述] 有一个国家被一条河划分为南北两部分,在南岸和北岸总共有N对城镇,每一城镇在对岸都有唯一的友好城镇.任何两个城镇都没有相同的友好城镇.每一对友好城镇都希望有一条航线来往.于是他们向政府提出 ...
最新文章
- 商汤IPO首日市值涨百亿,徐立感慨时代之幸:有机会改变世界!
- Flex与.NET互操作(九):FluorineFx.NET的认证(Authentication )与授权(Authorization)
- 如何考虑程序的优化性
- 20.QT-Qpixmap实现图片鼠标缩放,鼠标拖动示例(详解)
- url参数拼接 php,js URL参数的拼接方法比较_javascript技巧
- linux 安装校园客户端,Ubuntu Linux环境下校园网客户端安装使用
- win10程序员软件列表(持续更新中...)
- pdfbox / XSL + FOP 转换 PDF文档
- Linux tcp拥塞控制
- Altium Designer PCB与SCH参照布局
- 手机盾验证失败是什么意思_腾讯手机安全验证失败怎么回事
- 一个屌丝程序员的青春(一一零)
- 吴恩达的2022年终盘点:生成式AI、ViT、大模型
- 面试 java -----Socket编程
- 华师计算机在线作业答案,2016春季华师计算机基础在线作业答案
- SAP Router是个啥
- 恢复服务器安装信息被破坏了,服务器存储瘫痪数据恢复成功案例-服务器数据恢复...
- 发票 税率 普票 增值税发票
- C语言以延时的状态读取数据文件,CH376 U盘文件读写相关C语言代码
- 【Vue】快乐学习第四篇,组件访问及插槽使用
热门文章
- Xamarin开发笔记—百度在线语音合成
- IMP-00002: 无法打开 D:\orcldat\test_20111024.dmp 进行读取,rman备份
- 任何项目都适用的CMakeLists配置
- 计算机应用基础第二章,计算机应用基础第二章上机操作题
- docker+mysql创建用户名密码_docker构建私有仓库并设置仓库用户和密码
- java appender_log4j的Appenders配置方法
- adaptivitypara设置选0还是1_喝牛奶,选全脂还是低脂?家里人能不能喝同1种牛奶?...
- vip会员管理系统c语言,路西牌会员管理系统。
- python函数式编程读取数据时出现错误_Python编程中,函数遇到问题是抛出错误好还是约定返回值好?...
- python读取数据库数据类型_Python实现从SQL型数据库读写dataframe型数据的方法【基于pandas】...