[C++] 805 -- 最长上升子序列


例题描述

广场上站着一支队伍,她们是来自全国各地的扭秧歌代表队,现在有她们的身高数据,请你帮忙找出身高依次递增的子序列。

例如队伍的身高数据是(1、7、3、5、9、4、8)
其中依次递增的子序列有:
(1、7)
(1、3、5、9)
(1、3、4、8)等,
其中最长的长度为4

  • 输入描述:
    输入包含多组数据,每组数据第一行包含一个正整数n1 ≤ n ≤ 1000)。
    紧接着第二行包含n个正整数m1 ≤ n ≤ 10000),代表队伍中每位队员的身高。

  • 输出描述:
    对应每一组数据,输出最长递增子序列的长度。

示例1:

  • 输入:
    7
    1 7 3 5 9 4 8
    6
    1 3 5 2 4 6
  • 输出:
    4
    4

解题思路

典型的动态规划问题,定义数组和创建状态转移方程进行解决。

  1. 定义height来存储数据,f[i]为以height[i]结尾的元素的最长上升子序列元素个数,初始时将f所有内容全部初始化成1,因为子序列中至少包含一个元素
  2. 定义"状态转移方程":
    一开始先将f中的数据全部置为1,因为最小的子序列长度为1
    然后对于每个height[i],通过遍历[ height[0] ~ height[i-1] ]之间的数据,如果在该区间中找到一个height[j]height[j]小的元素,开始比较f[j]+1f[i]的大小,如果f[j]+1 > f[j]则更新f[i],因此:
  • height[i] > height[j]时:f[i] = max(f[i], f[j]+1)
  • height[i] <= height[j]时:继续取下一个数据。

代码实现

#include <iostream>
#include <vector>

using namespace std;

int main(){
	int n;
	while(cin >> n){
		vector<int> height(n, 0);
		for(int i = 0; i < n; i ++){
			cin >> height[i];
		}
		
		// f用来保存状态转移方程的结果,f[i]表示以height[i]结尾的最长上升子序列所包含元素的个数
		vector<int> f(n, 1);
		int result = 1;
		
		// 子序列中的数据一个一个增加
		for(int i = 1; i < n; i ++){
			// 从0开始统计到i位置,最长上升子序列长度
			for(int j = 0; j < i; j ++){
				if(height[i] > height[j]){
					f[i] = max(f[i], f[j] + 1);
				}
		}
		// 获取从0到i位置的最长子序列长度
		result = max(result, f[i]);
		}
	cout << result << endl;
	}
	return 0;
}

链接:https://www.nowcoder.com/questionTerminal/d83721575bd4418eae76c916483493de

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

giturtle

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值