zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    将元素平分成差值最小的两个集合(DP)
    新年趣事之打牌(01背包+唯一路径)
    offer(背包问题、DP)
    整数划分(完全背包)
    饭卡(DP)
    等和的分隔子集(dp)
    LaunchPad(思维)
    The flower(寻找出现m次以上,长度为k的子串)
    Morse code(多模式串匹配)
    平分娃娃(多重背包+二进制枚举)
  • 原文地址:https://www.cnblogs.com/enigma-aw/p/6265085.html
Copyright © 2011-2022 走看看