zoukankan      html  css  js  c++  java
  • AC_Dream 1216 G

    题意:
    有n个人每人有一个力气值Si,美丽值Bi,满足Bi>Bj&&Si>Sj 或者 Bi<Bj&&Si<Sj 的人可以
    一起参见晚会,问最多有多少人可以一起参见晚会。
    思路: 我们根据S从小到大将所有人排序,然后看B最长的上升子序列的长度求出来即可!
    在排序中优先对S排序,S相等的则对B进行由大到小的排序,why?
    也就是对于S相同的,我们先选取B最大的值插入LIS中,因为比如 S1=1, B1 = 1
    S1=1, B1 = 2, S1=1, B1 = 3, 如果不进行排序,直接按照求B中的lis,显然长度
    为3,显然是不对的,因为相同的S中只能选择一个B出来!所以就要对S相同的B进行
    降序排序! 这样就变成了一个裸lis!

     1 #include<iostream>
     2 #include<cmath>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cstdio>
     6 #define N 100005
     7 using namespace std;
     8 
     9 struct node{
    10     int x, y;
    11     int p;
    12 };
    13 
    14 bool cmp(node a, node b){
    15     if(a.x == b.x)
    16            return a.y > b.y;
    17     return a.x < b.x;
    18 }
    19 
    20 bool myCmp(node a, node b){
    21     return a.y <= b.y;//这里要写成 <=;因为upper_bound返回的是“元素值 >插入值”
    22                       //最后一个插入值的位置,元素值 == 插入值的时候,默认 元素值
    23                       // >插入值,但在该题中,相等的情况下不能算在lis中的! 
    24 }
    25 
    26 node a[N];
    27 node c[N];
    28 
    29 int pre[N], path[N];
    30 
    31 int main(){
    32     int n;
    33     while(scanf("%d", &n) != EOF){
    34         for(int i=0; i<n; ++i)
    35             scanf("%d%d", &a[i].x, &a[i].y), a[i].p = i+1;
    36             
    37         sort(a, a+n, cmp);    
    38         c[0] = a[0];
    39         pre[0] = 0;
    40         path[0] = 0;
    41         int len = 1;
    42         
    43         for(int i=1; i<n; ++i){
    44             int k = upper_bound(c, c+len, a[i], myCmp) - c;
    45             pre[i] = k ? path[k-1] : 0;//当前插入节点i的位置为k,它的前一个(k-1位置)元素的序号! 
    46             path[k] = i;//当前插入k位置的节点的序号 
    47             c[k] = a[i];
    48             if(k+1 > len) len = k+1;
    49         }
    50         int tmp = path[len-1];
    51         printf("%d
    ", len);
    52         printf("%d", a[path[len-1]].p);
    53         for(int i=len-2; i >= 0; --i){
    54             tmp = pre[tmp];
    55             printf(" %d", a[tmp].p);
    56         }
    57         printf("
    ");
    58             
    59     }
    60     return 0;
    61 }
    View Code
  • 相关阅读:
    Encryption (hard) CodeForces
    cf 1163D Mysterious Code (字符串, dp)
    AC日记——大整数的因子 openjudge 1.6 13
    AC日记——计算2的N次方 openjudge 1.6 12
    Ac日记——大整数减法 openjudge 1.6 11
    AC日记——大整数加法 openjudge 1.6 10
    AC日记——组合数问题 落谷 P2822 noip2016day2T1
    AC日记——向量点积计算 openjudge 1.6 09
    AC日记——石头剪刀布 openjudge 1.6 08
    AC日记——有趣的跳跃 openjudge 1.6 07
  • 原文地址:https://www.cnblogs.com/hujunzheng/p/4004777.html
Copyright © 2011-2022 走看看