LIS(最长上升子序列, 合唱队形)

2024-03-01 00:44

本文主要是介绍LIS(最长上升子序列, 合唱队形),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 最长上升子序列

直接使用动态规划:

 这个题目的关键就是在于我们选定一个数,然后利用这个数作为标准和这个数之前的所有数进行比较,如果比前面某一个数要大,那么就需要将这数自己本身的现存的最长长度与比较出来的数的最长加一(这里为什么要加一,因为需要加上前面的长度之外还需要将自己的长度也加上)进行比较,然后取最大。 最后我们还需要在全部所有的数进行一次比较找到最大值,这个最大值就是答案。

这个就是相当于模板 以供后面需要求最长上升子序列的时候使用

代码如下

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int dp[1000000];
int a[1000000];
int main()
{int n;cin>>n;for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<=n;i++){for(int j=0;j<i;j++)//这里值得注意的是,这个是将这个和前面所有的数都进行了一次比较{if(a[i]>a[j])dp[i]=max(dp[i],dp[j]+1);}}int ans=-1;for(int i=1;i<=n;i++){if(ans<dp[i])ans=dp[i];}cout<<ans<<endl;return 0;
}

灵感:对于动态规划来说每一个数组元素都有自己的含义,与上下都是存在关系的

 合唱队形

其实这一题也是一个有关最长上升子序列的问题,只不过是先是从1到n求一次上升子序列,然后再是从从n到1求一次上升子序列,然后再在这里面求最优解。

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int dp[1000000];
int dp1[1000000];
int a[1000000];
int sum[100000];
int main()
{int n;cin>>n;for(int i=1;i<=n;i++)cin>>a[i];for(int i=1;i<=n;i++){for(int j=0;j<i;j++)//这里值得注意的是,这个是将这个和前面所有的数都进行了一次比较{if(a[i]>a[j])dp[i]=max(dp[i],dp[j]+1);}}for(int i=n;i>=1;i--){for(int j=n+1;j>i;j--)//这里需要注意,初始化是从j=n+1开始的,如果不从n+1开始就会少加上自己{if(a[i]>a[j])dp1[i]=max(dp1[i],dp1[j]+1);}}int ans=-1;for(int i=1;i<=n;i++){sum[i]=dp[i]+dp1[i]-1;}for(int i=1;i<=n;i++){if(ans<sum[i])ans=sum[i];}cout<<n-ans<<endl;return 0;
}

 

这篇关于LIS(最长上升子序列, 合唱队形)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/760633

相关文章

poj3261(可重复k次的最长子串)

题意:可重复k次的最长子串 解题思路:求所有区间[x,x+k-1]中的最小值的最大值。求sa时间复杂度Nlog(N),求最值时间复杂度N*N,但实际复杂度很低。题目数据也比较水,不然估计过不了。 代码入下: #include<iostream>#include<algorithm>#include<stdio.h>#include<math.h>#include<cstring

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

uva 10131 最长子序列

题意: 给大象的体重和智商,求体重按从大到小,智商从高到低的最长子序列,并输出路径。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vect

hihocoder1050 : 树中的最长路

时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上回说到,小Ho得到了一棵二叉树玩具,这个玩具是由小球和木棍连接起来的,而在拆拼它的过程中,小Ho发现他不仅仅可以拼凑成一棵二叉树!还可以拼凑成一棵多叉树——好吧,其实就是更为平常的树而已。 但是不管怎么说,小Ho喜爱的玩具又升级换代了,于是他更加爱不释手(其实说起来小球和木棍有什么好玩的是吧= =)。小Ho手

POJ1631最长单调递增子序列

最长单调递增子序列 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.math.BigInteger;import java.util.StringTokenizer;publ

计蒜客 Skiing 最长路

In this winter holiday, Bob has a plan for skiing at the mountain resort. This ski resort has MM different ski paths and NN different flags situated at those turning points. The ii-th path from the

leetcode105 从前序与中序遍历序列构造二叉树

根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如,给出 前序遍历 preorder = [3,9,20,15,7]中序遍历 inorder = [9,3,15,20,7] 返回如下的二叉树: 3/ \9 20/ \15 7   class Solution {public TreeNode buildTree(int[] pr

PHP最长单一子串

<?php//方法一$s='abcccddddddcdefg';$max='';while($s!=''){$i=0; while($i<strlen($s) && $s[$i]==$s[0]) $i++;if ($i>strlen($max)){$max=substr($s,0,$i);} $s=substr($s,$i);}echo $m

day-50 求出最长好子序列 I

思路 二维dp,dp[i][h]表示nums[i] 结尾,且有不超过 h 个下标满足条件的最长好子序列的长度(0<=h<=k),二维数组dp初始值全为1 解题过程 状态转换方程: 1.nums[i]==nums[j],dp[i,h]=Math.max(dp[i,h],dp[j,h]+1) 2.nums[i]!=nums[j],dp[i,h]=Math.max(dp[i,h],dp[j,h-1

LeetCode:3177. 求出最长好子序列 II 哈希表+动态规划实现n*k时间复杂度

3177. 求出最长好子序列 II 题目链接 题目描述 给你一个整数数组 nums 和一个非负整数k 。如果一个整数序列 seq 满足在下标范围 [0, seq.length - 2] 中 最多只有 k 个下标i满足 seq[i] != seq[i + 1] ,那么我们称这个整数序列为好序列。请你返回 nums中好子序列的最长长度。 实例1: 输入:nums = [1,2,1,1,3],