zoukankan      html  css  js  c++  java
  • who is in front of me 解题报告

    题目描述:N(1<=N<=50005)个学生站成一个纵队,每个人只能看到前面身高比他高(严格大于)的人

                  求所有人中能看到的最大人数

    分析:对于某个人A,设前面第一个身高比他高的人是B。如果B不存在,那么A看到0个人。若B存在,那么A既能看到B,也能看到B所能看到的人(PS:题意是每个人只能看到身高严格大于自己的人,身高与自己相同的人视为看不见)。

            状态表示:F(x)表示x能看到的人数

            转移方程:F(A)=F(B)+1

            怎么才能很快找到A前面第一个比他高的人是谁?对于每个人x,记录他前面第一个比他高的人legt[x]。对于每个人A,我们比较A和A-1的高矮,如果A-1比A高,那么A-1自然是第一个比他高的人。否则我们寻找第一个比A-1高的人,也就是left[A-1],因为在A-1与left[A-1]之间的所有人,身高都比A-1矮,他们也自然不可能比A高。比较A与left[A-1]的高矮,如果不行再找left[left[A-1]]...,直到找到比A高的人,或者发现没有一个人比A高。然后可以用dp求解了。

            计算left的代码如下,h为每个人的高度:

            for(int i=0;i<N;i++){

            int j;

            for(j=i-1;j>=0&&h[j]<=h[i];j=left[j])   ;

            left[i]=j;

            }

     1 #include<cstdio>
     2 int T,n,h[50005],num[50005],left[50005];
     3 int main()
     4 {
     5     scanf("%d",&T);
     6     while(T--)
     7     {
     8         scanf("%d",&n);
     9         for(int i=0; i<n; i++)
    10             scanf("%d",&h[i]);
    11         int best=0;
    12         for(int i=0; i<n; i++)
    13         {
    14             int j;
    15             for(j=i-1; j>=0&&h[j]<=h[i]; j=left[j])
    16                 ;
    17             left[i]=j;
    18             if(j==-1) num[i]=0;
    19             else num[i]=num[j]+1;
    20             best= best>num[i] ? best : num[i];
    21         }
    22         printf("%d
    ",best);
    23     }
    24     return 0;
    25 }
  • 相关阅读:
    0713学期末了
    Oracle Redo日志的状态
    crontab调用shell访问sqlplus失败原因
    Solaris下批量杀进程
    oracle用户管理的完全恢复4:在ARCHIVELOG 模式(恢复打开的数据库)
    oracle用户管理的完全恢复3:在ARCHIVELOG 模式(恢复关闭的数据库)
    shell删除所有空行(忽略编码格式)
    oracle用户管理的完全恢复1:在NOARCHIVELOG 模式下执行恢复
    查看oracle用户权限
    OLTP与OLAP介绍
  • 原文地址:https://www.cnblogs.com/sage-blog/p/3646918.html
Copyright © 2011-2022 走看看