zoukankan      html  css  js  c++  java
  • 防线问题

    UVA1471

    Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu

     Status

    Description

    Download as PDF
     

    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 fortification 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 firing 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 first line of the input contains a positive integer Z$ le$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 first one contains one positive integer n$ le$2 . 105 denoting the number of towers. The second line containsn 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.

    Sample Input 

    2 
    9 
    5 3 4 9 2 8 6 7 1 
    7 
    1 2 3 10 4 5 6
    

    Output 

    4 
    6

    #include"iostream"
    #include"algorithm"
    #include"cstring"
    #include"cstdio"
    using namespace std;

    const int maxn=200000+10;
    const int Max=1000000000;

    int a[maxn],righ[maxn],lef[maxn],d[maxn],g[maxn];
    int main()
    {
    int T;
    cin>>T;
    while(T--)
    {
    int n;
    cin>>n;

    for(int i=0;i<n;i++) cin>>a[i];

    memset(righ,0,sizeof(righ));
    memset(lef,0,sizeof(lef));

    lef[0]=1;righ[n-1]=1;
    for(int i=n-2;i>=0;i--)
    {
    if(a[i]>=a[i+1]) righ[i]=1;
    else righ[i]=righ[i+1]+1;
    }
    for(int j=1;j<n;j++)
    {
    if(a[j]>a[j-1]) lef[j]=lef[j-1]+1;
    else lef[j]=1;
    }

    //为节省数一数所耗时间而做好的预处理表格,时间复杂度从O(n^3)可降到O(n^2),因为每次得到长度的时间从O(n)降到O(1)
    /*for(int j=0;j<n;j++) cout<<righ[j]<<" ";
    cout<<endl;
    for(int j=0;j<n;j++) cout<<lef[j]<<" ";
    cout<<endl;*/


    int ans=-1;

    //方法一:超时,耗时O(n^2)
    /*for(int i=0;i<n;i++)
    for(int j=i;j<n;j++)
    if(min(lef[j]+righ[i]-1,j-i)>ans) ans=min(lef[j]+righ[i]-1,j-i);*/

    //方法二:只遍历一次i,j完全靠二分查找,耗时O(nlogn)
    for(int i=1;i<=n;i++) g[i]=Max;

    for(int i=0;i<n;i++)
    {
    int k=lower_bound(g+1,g+n+1,a[i])-g; //找出的k肯定大于i,且k-i大于k+j-1.
    d[i]=k+righ[i]-1; //k即为从i开始的最大递增序列长度
    if(a[i]<g[lef[i]]) g[lef[i]]=a[i]; //维护左值有序表
    ans=max(ans,d[i]);
    }

    cout<<ans<<endl;
    }
    return 0;
    }

  • 相关阅读:
    10.C语言_Switch语句
    9.C语言_运算符和表达式分支语句
    问题是:js是如何实现鼠标移动到不同栏位切换对应的显示内容的?
    初识JavaScript,Ajax,jQuery,并比较三者关系
    使用母板页的内容页中js脚本应该放在什么位置,怎么调用
    如何让图片太大时自动缩小显示?
    网页视频播放器代码大全 + 21个为您的网站和博客提供的免费视频播放器
    flvplayer.swf flv视频播放器使用方法
    FileUpload检查上传文件扩展名,限制大小,创建路径存储
    几种代码生成器的叙述
  • 原文地址:https://www.cnblogs.com/zsyacm666666/p/4709088.html
Copyright © 2011-2022 走看看