#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre(){freopen("c://test//input.in","r",stdin);freopen("c://test//output.out","w",stdout);}
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;}
template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;}
const int N=1e5+10,M=0,Z=1e9+7,ms63=1061109567;
int casenum,casei;
int n;
struct A
{
int v,p;
bool operator < (const A& b)const
{
if(v!=b.v)return v<b.v;
else return p<b.p;
}
}a[N];
int p[N];
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;++i){scanf("%d",&a[i].v);a[i].p=i;}
sort(a+1,a+n+1);a[0].v=0;
for(int i=1;i<=n;++i)p[a[i].p]=i;
int i=1;
int rgt=1;
int ans=0;
while(i<=n)
{
while(i<=rgt)gmax(rgt,p[i++]);
++ans;
++rgt;
}
printf("%d\n",ans);
}
return 0;
}
/*
【trick&&吐槽】
【题意】
给你n(1e5)个数,每个数的取值范围是[1,1e9]。
让你对这n个数,划分为尽可能多的区间。
使得——
每个区间内的数做升序排序后,整体的所有数也是升序的。
【类型】
贪心
【分析】
这道题很有趣呀~~
首先,这道题,必然是有解的。
因为最坏情况下,我们也可以只划分为一个区间,然后必定是满足要求的。
我们发现,如果我们按照从左到右的顺序思考问题——
那么,每次划分一个区间,总的右界划分到了r的话,肯定是恰好包含了[1,r]中所有应该有的数。
什么叫[1,r]中应该有的数呢?
我们可以一开始把所有数按照(数值,位置)这个双关键字做排序。
然后,排序到的位置,就是如果要把这个数划分到合适的区间,至少需要划分到的r位置。
接下来,我们一直扫描,扫描到恰好使得——"前p位置的数就包含了这前p个数"。
这样就贪心做划分就好啦。很显然,"能划分就立刻划分"是基于贪心原则的最优做法。
这道题就这样AC喽!
【时间复杂度&&优化】
O(nlogn)
*/
【Codeforces Round 332 (Div 2)C】【贪心】Day at the Beach 最多区间数划分使得区间排序构成全局排序
最新推荐文章于 2020-06-22 23:22:53 发布