1. 程式人生 > >hdu5773 --2016多校第四場1010

hdu5773 --2016多校第四場1010

The All-purpose Zero

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1097    Accepted Submission(s): 271


Problem Description ?? gets an sequence S with n intergers(0 < n <= 100000,0<= S[i] <= 1000000).?? has a magic so that he can change 0 to any interger(He does not need to change all 0 to the same interger).?? wants you to help him to find out the length of the longest increasing (strictly) subsequence he can get.
Input The first line contains an interger T,denoting the number of the test cases.(T <= 10)
For each case,the first line contains an interger n,which is the length of the array s.
The next line contains n intergers separated by a single space, denote each number in S.

Output For each test case, output one line containing “Case #x: y”(without quotes), where x is the test case number(starting from 1) and y is the length of the longest increasing subsequence he can get.
Sample Input 2 7 2 0 2 1 2 0 5 6 1 2 3 3 0 0
Sample Output Case #1: 5 Case #2: 5 Hint

In the first case,you can change the second 0 to 3.So the longest increasing subsequence is 0 1 2 3 5.

題意:有一個序列,含有n個數,序列中的0可以變成任意數,問你變換完後最長上升子序列的長度是多少

顯然在最後面的0可以作為最長上升子序列的元素,那麼前面的0怎麼變換呢,思路是這樣的:把0去掉,做LIS 為了保證是添上0變換的數字後是上升的,把每個非0數減去前面包含的0的個數,然後len加上0的個數即可

樣例一 2 0 2 1 2 0 5 -> 2 (0) 1 0 1 (0) 3 新序列是 2 1 0 1 3 去掉了兩個0,新序列LIS=3

那麼原序列LIS=3+2 =5;

#include <stdio.h>
#include <iostream>
#include <stdlib.h>

using namespace std;
const int inf=0x3f3f3f3f,maxn=1e5+10;
int a[maxn],c[maxn],len;
int find(int R,int x)
{
    int L=1,mid;
    while(L<=R)
    {
        mid=(L+R)/2;
        if(c[mid]==x)return mid;
        else if(c[mid]<=x)
            L=mid+1;
        else R=mid-1;
    }
    return L;
}

int main()
{
    int n,m,T=1,t;
    int sum,j,zero,tot;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        sum=0;
        tot=0;
        int x;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            if(x==0)
                sum++;
            else
                a[tot++]=x-sum;
        }
        if(tot==0)
        {
             printf("Case #%d: %d\n",T++,n);
             continue;
        }

        len=0;
        c[0]=-inf;
        for(int i=0;i<tot;i++)
        {
            if(a[i]>c[len])
                j=++len;
            else
            j=find(len,a[i]);
            c[j]=a[i];
        }
        /*for(int i=1;i<=len;i++)
            cout<<c[i]<<" ";
        cout<<endl;*/
        printf("Case #%d: %d\n",T++,len+sum);
    }
}