HDU 4604 Deque 解题思路

题意:给定一个序列,从前往后取,然后给出一个可以从前面加和从后面加的特殊栈,但是这个栈必须保持递增,问你栈的最长长度为多少

解题思路:从后往前枚举第一个加入栈的队列,在求从后同时求不递增,不递减序列,然后在序列中找最小重复的,对于这个点的最大长度就是两个长度相加再减去最小重复的。

解题思路:

// File Name: e.c
// Author: darkdream
// Created Time: 2013年07月25日 星期四 10时17分58秒

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#include<ctype.h>
int a[100005];
int stackup[100005];
int stacklow[100005];
int ans[100005];
int toplow = 0 ;
int topup = 0 ;
int update(int stack[],int top,int temp)
{
    int low = 1;
    while(low <= top)
    {
        int mid = (low + top) / 2;
        if(temp >= stack[mid])
        {
            low = mid + 1;
        }
        else
        {
            top = mid - 1;
        }
    }
    return low;
}

int find(int stack[],int top,int temp)
{
    int low = 1 ;
    while(low <= top)
    {
        int mid = (low + top)/2;
        if(stack[mid] < temp )
        {
            low = mid + 1;
        }
        else
        {
            top = mid - 1 ;
        }
    }
    return top;

}

int main()
{

    //freopen("1005.in","r",stdin);
    //freopen("/home/plac/problem/output.txt","w",stdout);
    int t ;
    scanf("%d",&t);
    while(t--)
    {
        int n ;
        int max = 0 ;
        memset(stackup,0,sizeof(stackup));
        memset(stacklow,0,sizeof(stacklow));
        memset(a,0,sizeof(a));
        memset(ans,0,sizeof(ans));
        scanf("%d",&n);
        toplow = 0 ;
        topup = 0 ;
        for(int i =1 ; i<= n; i ++)
            scanf("%d",&a[i]);
        int ans1 , ans2 ;
        for(int i = n; i >= 1 ; i --)
        {

            int l1,l2 ;

            if(a[i] >= stackup[topup] )
            {
                topup ++ ;
                stackup[topup] = a[i];
                ans1 = topup;
            }
            else
            {
                int r = update(stackup,topup,a[i]);
                stackup[r] = a[i];
                ans1 = r;
                //printf("%d
",r);
            }

            l1 =ans1 - find(stackup,ans1,a[i]) - 1;


            if((-a[i]) >= stacklow[toplow] || !toplow )
            {
                toplow ++ ;
                stacklow[toplow] = -a[i];
                ans2 = toplow;

            }
            else
            {

                int r = update(stacklow,toplow,-a[i]);
                stacklow[r] = -a[i];
                ans2 = r;
            }

            l2 =ans2 - find(stacklow,ans2,-a[i]) - 1;

            // printf("%d %d *** %d %d
",l1,l2,ans1,ans2);
            if(ans2 - l2 + ans1 > ans1 - l1 + ans2)
                ans[i] = ans2 - l2 + ans1 - 1;
            else
                ans[i] = ans1 - l1 + ans2 - 1;
        }
        for(int i = 1; i <= n; i ++)
            if(ans[i] > max )
                max = ans[i];
        printf("%d
",max);
    }
    return 0 ;
}
View Code
没有梦想,何谈远方
原文地址:https://www.cnblogs.com/zyue/p/3213045.html