03 线型动态规划——LIS模型

LIS模型——最长上升子序列(Longest Increasing Subsequence)

【例1】最长上升子序列

Description
一个数的序列bi,当b1< b2 < ... < bS的时候,我们称这个序列是上升的。对于给定的一个序列(a1,a2,...,aN),我们可以得到一些上升的子序列(ai1, ai2, ..., aiK),这里1<=i1
你的任务,就是对于给定的序列,求出最长上升子序列的长度。
Input
输入的第一行是序列的长度N(1<=N<=1000)。第二行给出序列中的N个整数,这些整数的取值范围都在0到10000。
Output
最长上升子序列的长度。
Sample Input
6
1 6 2 5 4 7
Sample Output
4

【问题分析】
1、阶段和状态:
    f[i]:表示以a[i]为结尾的最长上升子序列的最大长度;
    阶段i表示前i个数,由于每个阶段只有一个状态,所以用一维数组表示;
2、状态转移方程:
    初始化:f[i]=1;
    每个元素至少都满足以自身作为长度为1的最长上升子序列。

    状态转移:f[i]=max{f[j]+1,j<i且a[j]<a[i]}
    利用1~(i-1)的f[j]更新当前位置f[i]的最大长度,如果a[i]>a[j],表明以a[i]可以接在a[j]后得到更长的LIS。

    遍历答案:answer=max{f[i]};(1<=i<=n)
    遍历每个元素a[i]结尾得到的最大上升子序列的长度,得到最大长度。

【图表演示】

【核心代码】

cin>>n;
for(i=1; i<=n; i++)
{
	cin>>a[i];    //初始化
	f[i]=1;
}
for(i=2; i<=n; i++)
	for(j=1; j<i; j++)
		if(a[j]<a[i]&&f[j]+1>f[i]) f[i]=f[j]+1;
max=1;
for(i=1; i<=n; i++)
	if(f[i]>f[max])max=i;
cout<<f[max]<<endl;

【扩展1】最长不下降子序列

Description
设有整数序列b1,b2,b3,……,bm, 若存在i1< i2 <i3 <…… <in,且bi1<bi2<bi3……<bin,
则称b1,b2,b3,……,bn,中有长度为N的不下降序列bi1,bi2,bi3,……,bin。求序列b1,b2,b3,……,bm中最大不下降序列的长度。
Input
第一行为n,第二行为用空格隔开的n个整数。
Output
第一行为输出最大个数max。
Sample Input
14
13 7 9 16 38 24 37 18 44 19 21 22 63 15
Sample Output
8

【题目提示】
最长不上子序列,a[i]与a[j]之间不相等
最长不下降子序列,a[i]与a[j]可以相等

【扩展2】最长不下降子序列

Description
设有整数序列b1,b2,b

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值