优化 最长上升子序列_干货|最长上升子序列长度及其优化与变种

作者:Izayoi_w

来源:牛客网

【题目描述】给定N个数,求这N个数的最长上升子序列的长度。

【样例输入】7

2 5 3 4 1 7 6

【样例输出】4

所谓最长上升子序列,就是给定一列数,求序列中严格上升(后一个数 > 前一个数)的子序列,这个子序列中数的位置不一定连续。

这是动态规划中的一个经典应用题目,动态规划的思想就是把问题分解为一些本质上还是相同问题的小问题,这些小问题的区别仅在于输入的参数不同,而每一个小问题的解都可以由比他参数更小的一些小问题的解推出,最小的小问题有显而易见的解,这被称之为边界。最长上升子序列(LIS)问题也是这样。

比如我们用a[]这个数组存数列,a[i]表示数列的第i个数字;定义一个dp[]数组,dp[i]表示以a[i]结尾的LIS的长度。

dp[i]一定是把a[i]加到以a[i]之前的数(a[1] ~ a[i-1])中某一个数结尾的LIS后面的,那么dp[i]一定等于dp[1] ~ dp[i-1]中某一个数+1。假设这个数为dp[j],按照LIS的定义,其对应的a[j]一定小于a[i]。所以此时就很明确了:令1<=j<=i-1,且a[j]

然后在所有的dp[i]中取一个最大的即是整个数列的最长上升子序列的长度。

按照这个思想写出来的代码:

#include #include #include #include #include #include #include using namespace std;

const int INF = 0x3f3f3f3f;

const int MAXN = 1e9;

typedef long long ll;

int a[30], dp[30];

int main()

{

int n;

scanf("%d", &n);

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

scanf("%d", &a[i]);

int LIS = 1;

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

{

dp[i] = 1;

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

if(a[j]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值