动态规划:最长不下降序列(LIS)

本文介绍了一种寻找数字序列中最长非降子序列的方法。通过动态规划算法,该方法能够找出给定序列中最长的非递减子序列,并返回其长度。例如,在序列123-1-279中,最长的非降子序列为12379,长度为5。

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

在一个数字序列中,找到一个最长的子序列,可以不连续,使得这个子序列是不下降的(非递减的)
样例
1 2 3 -1 -2 7 9
最长不下降的子序列是 1 2 3 7 9,长度为5

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn =1000+5;
int a[maxn],dp[maxn];
int main(){
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	int ans=-1;
	for(int i=0;i<n;i++){
		dp[i]=1;
		for(int j=0;j<i;j++){
			if(a[i] >= a[j] && dp[j]+1 > dp[i])
			dp[i]=dp[j]+1;
		}
		ans=max(ans,dp[i]);
	}
	cout<<ans;
	
	return 0;
} 
在 Java 中,动态规划是一种解决问题的有效策略,特别适用于优化解具有重叠子问题和最优子结构的问题,如计算最长下降序列(Longest Increasing Subsequence, LIS)。这里是一个简单的 Java 代码示例,用于找到数组中的最长递增子序列: ```java public class LongestIncreasingSubsequence { public static int lengthOfLIS(int[] nums) { if (nums == null || nums.length == 0) return 0; // 使用斐波那契堆(优先队列)辅助实现 PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> b[0] - a[0]); for (int num : nums) { pq.offer(new int[] {num, pq.size()}); // 用当前值num和子序列长度作为键 while (!pq.isEmpty() && pq.peek()[0] < num) { int[] top = pq.poll(); // 移除最小的元素,即前一个较短子序列 if (top[1] + 1 > pq.peek()[1]) { pq.offer(new int[]{num, top[1] + 1}); // 如果加上当前值会更长,则更新堆中的数据 } } } return pq.peek()[1]; // 返回堆顶的最大子序列长度 } public static void main(String[] args) { int[] nums = {10, 9, 2, 5, 3, 7, 101, 18}; System.out.println("Length of the longest increasing subsequence: " + lengthOfLIS(nums)); } } ``` 这个代码首先初始化一个优先队列(堆),然后遍历输入数组。对于每个数字,它会检查是否可以将其添加到现有子序列的末尾,如果可以,就从堆中移除最短的子序列并尝试替换。最后返回堆顶的子序列长度,即最长递增子序列的长度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值