//依据柳婼学姐的思路写的:
//(思路整理:)
//仍然是找出降序子序列的最少个数
//然而因为每次比较的都只是每一个子序列最后的元素,
//同时(之前还漏了这一点)还应该做到每一次加入的元素选择的位置是距离自己最近的值所在的子序列
//举例子
// 80
// 50
// 30
//接下来如果是40和60 ,如果安插在第一个找到的可以安插的地方,即80后面,那么60就要新开一个轨道了
//所以上面那个原则还能避免多余空间开辟导致的浪费
//所以可以用set存放这些末尾的值,因为在set中值按照升序排列,所以再利用
//upper_bound就能找到离他最近能安插的序列了,之后之前的序列代表值可以被删除,变相
//地由新值代替。
#include<bits/stdc++.h>
using namespace std;
int main()
{
set<int> s;
s.insert(0);//非常关键,空集合会让很多操作失效,重要性
//相当于'\0'对于字符数组
int n,t;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>t;
if(t<=*s.rbegin())//如果连最大的都比他小,就不用谈什么代替删除了
s.erase(s.upper_bound(t));
s.insert(t);
}
cout<<s.size()-1;
return 0;
}
//这个用vector实现的,无奈太慢了。
//题目的另外一种问法就是给你一段数列,请你按照降序排序方法生成最少的子序列。
//因为刚学,所以巩固一下:
//vector <int>v[100005];——定义vector数组
//*(v[j].end()-1) ——访问最后一个元素
//那么其实不用这么多的东西,多余了
//(现场构思)与已存入的最小的数比较,如果小,就自动替代
//不行,例如:
//5
//3
//2
//这个时候再来一个4,难道因为比2大就不能插了吗?
//若是记录当前最小值的最大值?
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n; cin>>n;
int i,j;
int cnt=1; vector <int>v[100005];
int t; cin>>t; v[1].push_back(t);
for(i=1;i<n;i++)
{
cin>>t;
for(j=1;j<=cnt;j++)
{
if(*(v[j].end()-1)>t)
{
v[j].push_back(t);
break;
}
}
if(j>cnt)
{
cnt=j;
v[cnt].push_back(t);
}
}
cout<<cnt;
return 0;
}
列车调度
最新推荐文章于 2019-09-18 14:44:00 发布