6. Redraiment的走法(求最长递增子序列)

博客探讨了Redraiment走梅花桩问题,转化为寻找最长递增子序列的算法。通过分析样例输入和输出,解释了如何利用C++的vector和lower_bound()函数来解决这一问题,并详细阐述了代码理解,包括vector的动态数组特性以及lower_bound()函数在有序区间查找的功能。此外,还提到了其他可能的解法。

题目描述

Redraiment是走梅花桩的高手。Redraiment总是起点不限,从前到后,往高的桩子走,但走的步数最多,不知道为什么?你能替Redraiment研究他最多走的步数吗? 

样例输入

6

2 5 1 5 4 5

样例输出

3

Example: 

6个点的高度各为 2 5 1 5 4 5 

如从第1格开始走,最多为3步, 2 4 5 

从第2格开始走,最多只有1步,5 

而从第3格开始走最多有3步,1 4 5 

从第5格开始走最多有2步,4 5

所以这个结果是3。

一.代码及运行结果

这里参考了牛客网网友:"冉人二土三金" 提交的代码

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;
int main(){
    int n;
    while(cin>>n){  //n为输入数据的个数 
        int a[n];   //a[n]是存放数据的数组,然后依次输入n个数据 
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        
        vector<int> ve;    //定义一个整型向量 ve 
        ve.push_back(a[0]); //在向量的尾部加入数组的一个数据a[0]
        for(int i=1;i<n;i++){  
		         
            if(lower_bound(ve.begin(),ve.end(),a[i])==ve.end()) ve.push_back(a[i]);  
            else *lower_bound(ve.begin(),ve.end(),a[i])=a[i]; 
    }
    cout<<ve.size()<<endl;
}
    return 0;
}

 

二.代码理解与解释

1.vector的使用:

参考:C++中Vector的用法

vector可以理解为动态数组,与数组相比它能够根据需要随时调整自身大小来容纳元素.

使用时, 应包含 #include<vector> .

vector<int> ve        //定义一个整型向量ve.
ve.push_back(elem)    //在尾部加入一个数据
ve.begin()            //传回迭代器第一个数据的地址
ve.end()              //指向迭代器末端元素的下一个,即指向一个不存在的元素
ve.size()             //返回容器中实际数据的个数

关于Vector的详细使用方法,可参考这个博客.

2. lower_bound()函数的使用

其作用是: 查找有序区间中第一个大于或等于给定值的元素的位置. 其在使用时需要有: #include<algorithm>

lower_bound(ve.begin(),ve.end(),a[i])   //即返回在ve.begin()和ve.end()区间内,大于等于a[i]的第一个元素的位置.

关于lower_bound()函数的详细使用,可参照这个博客.

3.关于代码理解

循环时 , i从1开始, 判断大于或等于a[i] 的元素是否在向量ve中存在, 如果不存在,那么将a[i] 放在向量尾部,否则用a[i] 取代ve中第一次出现的大于或等于a[i]的值, i加1,循环下去,可将数组a[n]的最长递增子序列放在 ve中, ve中数据的个数即为最长子序列的长度.


三. 其他解法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值