zoukankan      html  css  js  c++  java
  • uva 1471 defence lines——yhx

    After the last war devastated your country, you - as the king of the land of Ardenia - decided it was
    high time to improve the defense of your capital city. A part of your forti cation is a line of mage
    towers, starting near the city and continuing to the northern woods. Your advisors determined that the
    quality of the defense depended only on one factor: the length of a longest contiguous tower sequence
    of increasing heights. (They gave you a lengthy explanation, but the only thing you understood was
    that it had something to do with ring energy bolts at enemy forces).
    After some hard negotiations, it appeared that building new towers is out of question. Mages of
    Ardenia have agreed to demolish some of their towers, though. You may demolish arbitrary number of
    towers, but the mages enforced one condition: these towers have to be consecutive.
    For example, if the heights of towers were, respectively, 5, 3, 4, 9, 2, 8, 6, 7, 1, then by demolishing
    towers of heights 9, 2, and 8, the longest increasing sequence of consecutive towers is 3, 4, 6, 7.
    Input
    The input contains several test cases. The rst line of the input contains a positive integer Z  25,
    denoting the number of test cases. Then Z test cases follow, each conforming to the format described
    below.
    The input instance consists of two lines. The rst one contains one positive integer n  2  105
    denoting the number of towers. The second line contains n positive integers not larger than 109
    separated by single spaces being the heights of the towers.
    Output
    For each test case, your program has to write an output conforming to the format described below.
    You should output one line containing the length of a longest increasing sequence of consecutive
    towers, achievable by demolishing some consecutive towers or no tower at all.

     1 #include<cstdio>
     2 #include<set>
     3 #include<cstring>
     4 #define M(a) memset(a,0,sizeof(a))
     5 using namespace std;
     6 struct ele
     7 {
     8     int a,g;
     9     bool operator < (const ele & x) const
    10     {
    11         return a<x.a;
    12     }
    13 }e1,e2;
    14 set<ele> s;
    15 set<ele>::iterator it;
    16 int a[200010],f[200010],g[200010];
    17 int main()
    18 {
    19     int i,j,k,m,n,p,q,x,y,z,t,ans;
    20     bool b;
    21     scanf("%d",&t);
    22     while (t--)
    23     {
    24         M(a);
    25         M(f);
    26         M(g);
    27         s.clear();
    28         scanf("%d",&n);
    29         for (i=1;i<=n;i++)
    30           scanf("%d",&a[i]);
    31         for (i=n;i>=1;i--)
    32           if (a[i]<a[i+1]) f[i]=f[i+1]+1;
    33           else f[i]=1;
    34         for (i=1;i<=n;i++)
    35           if (a[i]>a[i-1]) g[i]=g[i-1]+1;
    36           else g[i]=1;
    37         e1.a=a[1];
    38         e1.g=g[1];
    39         s.insert(e1);
    40         ans=1;
    41         for (i=2;i<=n;i++)
    42         {
    43             e1.a=a[i];
    44             e1.g=g[i];
    45             it=s.lower_bound(e1);
    46             b=1;
    47             if (it!=s.begin())
    48             {
    49                 e2=*(--it);
    50                 if (f[i]+e2.g>ans) ans=f[i]+e2.g;
    51                 if (e1.g<=e2.g) b=0;
    52             }
    53             if (b)
    54             {
    55                 s.erase(e1);
    56                 s.insert(e1);
    57                 it=s.find(e1);
    58                 it++;
    59                 while (it!=s.end()&&(*it).a>e1.a&&(*it).g<=e1.g) s.erase(it++);
    60             }
    61         }
    62         printf("%d
    ",ans);
    63     }
    64 }

    因为不太会写stl,所以照着标程边抄边改边理解。

    对于每个元素求出以它开头和结尾的最长递增子序列长度f[i]和g[i],那么对于每一个确定的后端点i,只需要找到满足a[j]<a[i]的最大g[j]即可。

    易知如果a[j']>a[j]且g[j']<=g[j],则j’一定没用,因为j不但比他容易用,还比他效果好。

    用set存储所有满足条件的pair<a[j],g[j]>,按a排序【则g也一定有序】。对于每个i,用lower_bound找到第一个>=它的,也就找到了最后一个<它的。用其更新答案。

    用i更新完ans之后,需要把i也插入set中,为后面的元素服务。先判断i是否要插入(也就是有没有比他好的,只需要和刚才找见的最后一个<它的比较即可),再看插入之后可以删掉哪些元素(也就是没有它好的,向他前面一个一个找)。

  • 相关阅读:
    Code First 迁移
    使用C#创建Windows服务 并发布Windows 服务
    线程(Thread,ThreadPool)、Task、Parallel
    用《捕鱼达人》去理解C#中的多线程
    Visual Studio提示“无法启动IIS Express Web服务器”的解决方法 调试闪退
    防cc攻击策略
    多线程和异步的异同和使用场景
    JQuery Checkbox 获取多选值 Checkbox选中个数
    C# 说说lock到底锁谁?(1)
    C# 说说lock到底锁谁?(2)
  • 原文地址:https://www.cnblogs.com/SBSOI/p/5574994.html
Copyright © 2011-2022 走看看