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
    
    */
  • 相关阅读:
    linux查看日志文件内容命令tail、cat、tac、head、echo
    改变自己的128种方法,教你变得更优秀!
    php 23种设计模式
    Swoole消息推送
    PHP 出现 502 解决方案
    【centos7】添加开机启动服务/脚本
    curl 参数配置详解
    i系列标准-互联网周刊
    MySQL 设计与开发规范2
    Cocos Creator webviw网页置顶增加返回键的方法
  • 原文地址:https://www.cnblogs.com/djingjing/p/8687746.html
Copyright © 2011-2022 走看看