• 51nod 1218 最长递增子序列 V2(dp + 思维)


    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1218

    题解:先要确定这些点是不是属于最长递增序列然后再确定这些数在最长递增序列中出现的次数,如果大于1次显然是可能出现只出现1次肯定是必然出现。那么就是怎么判断是不是属于最长递增序列,这个只要顺着求一下最长递增标一下该点属于长度几然后再逆着求一下最长递减标一下该点属于长度几如果两个下标之和等于最长长度+1那么该点就属于最长递增序列,然后就是求1~len(len表示最长的长度)中各个长度出现的次数就行。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #define inf 0X3f3f3f3f
    using namespace std;
    const int M = 5e4 + 10;
    int a[M] , b[M] , dpa[M] , dpb[M] , vis[M];
    bool vs[M];
    int binsearch(int l , int r , int num) {
        int mid = (l + r) >> 1;
        int ans = 0;
        while(l <= r) {
            mid = (l + r) >> 1;
            if(b[mid] > num) r = mid - 1;
            else {
                ans = mid;
                l = mid + 1;
            }
        }
        return ans;
    }
    int binsearch2(int l , int r , int num) {
        int mid = (l + r) >> 1;
        int ans = 0;
        while(l <= r) {
            mid = (l + r) >> 1;
            if(b[mid] < num) r = mid - 1;
            else {
                ans = mid;
                l = mid + 1;
            }
        }
        return ans;
    }
    int main() {
        int n;
        scanf("%d" , &n);
        for(int i = 1 ; i <= n ; i++) scanf("%d" , &a[i]);
        int len = 0;
        b[0] = -1;
        for(int i = 1 ; i <= n ; i++) {
            if(a[i] > b[len]) {
                len++;
                b[len] = a[i];
                dpa[i] = len;
                continue;
            }
            else {
                int pos = binsearch(1 , len , a[i]);
                b[pos + 1] = min(b[pos + 1] , a[i]);
                dpa[i] = pos + 1;
            }
        }
        int len2 = 0;
        memset(b , inf , sizeof(b));
        for(int i = n ; i >= 1 ; i--) {
            if(a[i] < b[len2]) {
                len2++;
                b[len2] = a[i];
                dpb[i] = len2;
            }
            else {
                int pos = binsearch2(1 , len2 , a[i]);
                b[pos + 1] = max(b[pos + 1] , a[i]);
                dpb[i] = pos + 1;
            }
        }
        memset(vs , false , sizeof(vs));
        for(int i = 1 ; i <= n ; i++) {
            if(dpa[i] + dpb[i] == len + 1) {
                vis[dpa[i]]++;
                vs[i] = true;
            }
        }
        printf("A:");
        for(int i = 1 ; i <= n ; i++) {
            if(vis[dpa[i]] > 1 && vs[i]) printf("%d " , i);
        }
        printf("
    ");
        printf("B:");
        for(int i = 1 ; i <= n ; i++) {
            if(vis[dpa[i]] == 1 && vs[i]) printf("%d " , i);
        }
        printf("
    ");
        return 0;
    }
    
  • 相关阅读:
    webpack简介与使用
    webpack使用小记
    H5常用技巧
    mac 终端 常用命令
    vue.js学习资料
    git clean(转载)
    HTML5 移动端的上下左右滑动问题
    HTML5+CSS3 loading 效果收集--转载
    使用Chrome DevTools的Timeline分析页面性能
    phantomjs 是什么?----主要是mac下面
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/7116959.html
Copyright © 2020-2023  润新知