zoukankan      html  css  js  c++  java
  • hihocoder_offer收割编程练习赛53_3 最长一次上升子序列

    题目链接: https://hihocoder.com/contest/offers53/problem/3

    解题思路: 最长一次上升子序列,必然是一个先下降,然后上升一次,然后接着下降的序列。这就把原问题分解成两个子问题,求1--i的最长下降子序列,和i到n-1的最长下降子序列,然后拼起来求一个最大值。还有一个特殊的情况,所有的序列都是下降的,此时就是整个序列的长度。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int imax_n = 100005;
    
    int a[imax_n];
    int b[imax_n];
    int da[imax_n];
    int db[imax_n];
    int pb[imax_n];
    int n;
    
    int x[imax_n];
    int cnt;
    
    int b_search(int x[], int n, int k)
    {
        int l = 0;
        int r = n - 1;
        while (l <= r)
        {
            int mid = l + (r - l) / 2;
            // printf("l=%d, r=%d, a[mid] = %d, k = %d
    ", l, r, x[mid], k);
            if (x[mid] <= k)
            {
                l = mid + 1;
            }
            else
            {
                r = mid  - 1;
            }
        }
        return l;
    }
    
    void findLongestIns(int a[], int da[], int n)
    {
        da[0] = 1;
        cnt = 0;
        x[cnt++] = a[0];
        for (int i = 1; i < n; ++i)
        {
            int pos = b_search(x, cnt, a[i]);
            da[i] = pos + 1;
            if (pos == cnt)
            {
                x[cnt++] = a[i];
            }
            else if (a[i] < x[pos])
            {
                x[pos] = a[i];
            }
        }
    }
    
    int p_search(int x[], int n, int k)
    {
        int l = 0;
        int r = n-1;
        while (l <= r)
        {
            int mid = l + (r - l) / 2;
            if (x[mid] >= k)
            {
                l = mid + 1;
            }
            else
            {
                r = mid - 1;
            }
        }
        return l;
    }
    
    void findLongestDes(int a[], int da[], int n)
    {
        da[0] = 1;
        cnt = 0;
        x[cnt++] = a[0];
        for (int i = 1; i < n ; ++i)
        {
            int pos = p_search(x, cnt, a[i]);
            da[i] = pos + 1;
            if (pos == cnt)
            {
                x[cnt++] = a[i];
            }
            else if (a[i] > x[pos])
            {
                x[pos] = a[i];
            }
        }
    }
    
    int main()
    {
        scanf("%d", &n);
        for (int i = 0; i < n; ++i)
        {
            scanf("%d", &a[i]);
            b[n - i - 1] = a[i];
        }
        findLongestDes(a, da, n);
    //    for (int i = 0; i < n; ++i)
    //    {
    //        printf("%d ", da[i]);
    //    }
    //    printf("
    ");
        findLongestIns(b, db, n);
    //    for (int i = n-1; i >=0; i--)
    //    {
    //        printf("%d ", db[i]);
    //    }
    //    printf("
    ");
        pb[0] = db[0];
        for (int i = 1; i < n; ++i)
        {
            pb[i] = max(pb[i-1], db[i]);
        }
    //    for (int i = 0; i < n; ++i)
    //    {
    //        printf("%d ", pb[i]);
    //    }
    //    printf("
    ");
        int ans = 0;
        for (int i = 1; i < n; ++i)
        {
            ans = max(ans, da[i-1] + pb[n - i - 1]);
        }
        ans = max(ans, db[0]);
        printf("%d
    ", ans);
        return 0;
    }
    
    /*
        test
        5
        5 4 3 2 1
        5
        1 2 3 4 5
    
    */
  • 相关阅读:
    JavaScript getElementByID() not working
    [转] 从此不再惧怕URI编码:JavaScript及C# URI编码详解
    win 8.1 突然没有了声音 -- 解决办法
    升级打怪第一天 -------字符串重复
    Flex布局
    HTML 的全局事件属性
    CSS position 相对定位和绝对定位
    将1100秒转换为分秒格式
    新手小白的上路之旅
    谈谈我对Manacher算法的理解
  • 原文地址:https://www.cnblogs.com/djingjing/p/8687746.html
Copyright © 2011-2022 走看看