题意:给定一个n,以下n个数(假定为fi),要求构造一个n个数的序列,使得这个序列每一个位置的最大上升子序列的长度等于对应的fi。
其实这道题是个很简单的题,之前7月也在BC上做到过,为什么要写呢,因为思维过程还是挺好的。
考虑我们要构造这么一个序列,每个位置要满足什么条件呢?首先,对于一个位置,这个位置之前的那些位置,如果它们的fi大于等于这个位置上的fi,那么我们给这个位置放的数一定要小于前面那些位置上的数,而对于小于这个位置的fi的那些位置,我们的值又要大于它们的值,也就是说安排后我们要保证fi大的位置分配给它的数一定要大。那么对于两个fi相同的位置,怎么办呢?一定是位置靠后的那个分配的小。为什么呢,很显然,如果大了的话,就可以使最大上升子序列的长度加1了。
所以这道题做法就出来了:以fi为第一关键字升序,下标为第二关键字降序,排一道序,然后对应地填上1-n这些数就好了。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 100005 4 inline int read(){ 5 int x=0,f=1; char a=getchar(); 6 while(a<'0' || a>'9') {if(a=='-') f=-1; a=getchar();} 7 while(a>='0' && a<='9') x=x*10+a-'0',a=getchar(); 8 return x*f; 9 } 10 struct data{ 11 int num,pos; 12 bool operator < (const data& w)const{ 13 if(num==w.num) return pos>w.pos; 14 return num<w.num; 15 } 16 }a[N]; 17 int n,ans[N]; 18 int main(){ 19 n=read(); 20 for(int i=1;i<=n;i++) 21 a[i].num=read(),a[i].pos=i; 22 sort(a+1,a+1+n); 23 for(int i=1;i<=n;i++) 24 ans[a[i].pos]=i; 25 for(int i=1;i<=n;i++) 26 printf("%d ",ans[i]); 27 return 0; 28 }