首页 > 代码库 > UTR#2 T1

UTR#2 T1

题意:给定一个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 }

 

UTR#2 T1