题目背景

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 。

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

样例输入<button class="jsk&#45;btn&#45;link jsk&#45;fr jsk&#45;text&#45;sm" data&#45;clipboard&#45;target="&#35;id0079050505622249070002" data&#45;jsk&#45;popover="&#123;content&#58; &#39;复制成功&#39;&#44; theme&#58; &#39;success sm&#39;&#125;" id="id00202514927364702670001">复制</button>

1
6
4 1 5 2 6 3

样例输出<button class="jsk&#45;btn&#45;link jsk&#45;fr jsk&#45;text&#45;sm" data&#45;clipboard&#45;target="&#35;id00135441399749090420004" data&#45;jsk&#45;popover="&#123;content&#58; &#39;复制成功&#39;&#44; theme&#58; &#39;success sm&#39;&#125;" id="id00155449255510518030003">复制</button>

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\n",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), '\0', 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 == '\n');
    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';
        }
    }
}