[CF1450F] The Struggling Contestant

[CF1450F] The Struggling Contestant - 构造

Description

求一个 (1..n) 的全排列 (p),代价定义为满足 (|p_{i+1}-p_i|>1)(i) 的个数。需要满足 (a_{p_i} e a_{p_{i+1}} forall 1leq i< n)

Solution

对于每对连续相同的数,必须在这里断开,因此如果有 k 对,就需要切至少 k 次

但如果出现这样的情况,就不够了

1--1, 1--1, 1--2

观察发现,如果一个数作为端点出现的次数超过 (k+2),那么我们需要额外切若干次

但显然不会有两个数同时超过 (k+2),所以我们只需要考虑最大数即可

如果一个数在原数组中的出现次数大于总数的一半(上取整),那么一定无解(例子 11111222,1111222

#include <bits/stdc++.h>
using namespace std;

#define int long long

void solve()
{
    int n;
    cin >> n;
    vector<int> a(n + 2);
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    int k = 0;
    for (int i = 1; i < n; i++)
        if (a[i] == a[i + 1])
            ++k;
    map<int, int> mp, mm;
    for (int i = 1; i <= n; i++)
        mm[a[i]]++;
    int xx = 0;
    for (auto [x, y] : mm)
        xx = max(xx, y);
    if (xx > (n + 1) / 2)
    {
        cout << -1 << endl;
        return;
    }
    mp[a[1]]++;
    mp[a[n]]++;
    for (int i = 1; i < n; i++)
        if (a[i] == a[i + 1])
            mp[a[i]]++, mp[a[i + 1]]++;
    int mx = 0;
    for (auto [x, y] : mp)
        mx = max(mx, y);
    cout << max(k, mx - 2) << endl;
}

signed main()
{
    ios::sync_with_stdio(false);

    int t;
    cin >> t;

    while (t--)
    {
        solve();
    }
}
原文地址:https://www.cnblogs.com/mollnn/p/14523526.html