• 2019 计蒜之道 初赛 第二场 B. 百度AI小课堂-上升子序列(简单) ( 实现)


    题目背景

    91029102 年 99 月 22 日,百度在 X 市 XX 中学举办的第一场 AI 知识小课堂大获好评!同学们对矩阵的掌握非常棒。

    今天的 AI 知识小课堂的第二场开讲啦。本场 AI 知识小课堂老师教授的是数组的相关知识---上升子序列。

    题目描述

    给一个长度为 nn 的数组 aa 。试将其划分为两个严格上升子序列,并使其长度差最小。

    输入格式

    输入包含多组数据。

    数据的第一行为一个正整数 TT ,表示数据组数。

    每组数据包括两行:

    第一行包括一个正整数 nn 。

    第二行包括一个长度为 nn 的数组 aa。

    输出格式

    对于每组数据输出一行一个整数,表示两个子序列的最小长度差。若不存在划分方案则输出 -11 。

    数据范围

    T le 10 , n le 10^5 , a_i in [ 0 , 2^{30} ]T10,n105,ai[0,230] 。

    特殊限制及约定:合法的划分方案数不超过 11 。

    输出时每行末尾的多余空格,不影响答案正确性

    样例输入

    1
    6
    4 1 5 2 6 3

    样例输出

    0


    思路:
    紧扣题目给的特殊约定,合法的方案数不超过1个,
    那么意思就是,要么没有满足条件的方案(例如 6 个数, 分别是 6 6 6 6 6 6 ),
    或者是 只有一个合法的方案数,例如样例。

    这样我们从第一个数下手,如果存在一个方案,那么一定有一个lis 是以第一个数为起点的。
    并且下一个比a[1] 大的数 一定被和a[1] 分在一起。
    然后开始数组标记一下哪些数被分到了第一个子序列,然后剩下的子序列是否符合严格的递增的关系。

    细节见代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define rt return
    #define dll(x) scanf("%I64d",&x)
    #define xll(x) printf("%I64d
    ",x)
    #define sz(a) int(a.size())
    #define all(a) a.begin(), a.end()
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
    using namespace std;
    typedef long long ll;
    ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
    ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
    ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;}
    inline void getInt(int* p);
    const int maxn = 1000010;
    const int inf = 0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    int a[maxn];
    int n;
    int vis[100010];
    int main()
    {
        // freopen("D:\common_text\c101ode_stream\in.txt","r",stdin);
        //freopen("D:\common_text\code_stream\out.txt","w",stdout);
        int t;
        gbtb;
        cin >> t;
        while (t--)
        {
            MS0(vis);
            cin >> n;
            repd(i, 1, n)
            {
                cin >> a[i];
            }
            int cnt = 1;
            int temp = a[1];
            int num = 1;
            repd(i, 2, n)
            {
                if (a[i] > temp)
                {
                    vis[i] = 1;
                    temp = a[i];
                    num++;
                    cnt++;
                }
            }
            temp = -1;
            repd(i, 2, n)
            {
                if (vis[i] == 0)
                {
                    // cout<<i<<" ";
                    if (temp == -1)
                    {
                        temp = a[i];
                        num++;
                        cnt--;
                    }
                    if (a[i] > temp)
                    {
                        temp = a[i];
                        num++;
                        cnt--;
                    }
                }
    
            }
            // cout<<endl;
            // cout<<num<<" "<<cnt<<endl;
            if (num == n)
            {
                cout << abs(cnt) << endl;
            } else
            {
                cout << -1 << endl;
            }
        }
    
    
    
        return 0;
    }
    
    inline void getInt(int* p) {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        }
        else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }


    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    886. 求组合数 II(模板)
    885.求组合数 I(模板)
    线性同余方程(同余+扩展欧几里得模板)
    扩展欧几里得(模板)
    乘法逆元(模板)
    求欧拉函数(模板)
    最大公约数(欧几里得算法/辗转相除法)
    求约数之和
    New beginning~
    CSP-S 2019游记
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/10955351.html
Copyright © 2020-2023  润新知