The Contest(思維+前綴和)

題目鏈接:E. The Contest

題意:
三個人,每個人有一些數字,組合起來是一個排列,現在給你三個人手中數字的數量以及手中是哪幾個數,每次操作可以把一個人手中的數字給另個人,問你最少多少次操作使得第一個人擁有這個排列的某個前綴,第三個人擁有這個排列的某個後綴,第二個人擁有中間剩下的部分(允許有人沒有數字)。

思路:

  1. 看到三個人操作,我們先看兩個人操作時的情況:
    假設到最後,第一個人擁有1 ~ i,第二個人擁有i+1 ~ n,那麼最小操作數爲第二個人1~i中擁有的數字加上第一個人i+1 ~ n中擁有的數字。我們可以採用前綴和,cnt1[k]表示第一個人前k個數中擁有的個數,cnt2[k]表示第二個人前k個數中擁有的個數,則表達式爲:
    cnt2[i]+cnt1[n]−cnt1[i]
  2. 受到啓發我們看三個人操作時的情況:
    假設到最後,第一個人擁有1 ~ i,第二個人擁有i+1 ~ j,第三個人擁有j+1 ~ n,那麼最小操作數爲第二個人和第三個人1 ~ i中擁有的個數加上第一個人和第三個人i+1 ~ j中擁有的個數加上第一個人和第二個人j+1 ~ n中擁有的個數。我們可以採用前綴和,cnt1[k]表示第一個人前k個數中擁有的個數,cnt2[k]表示第二個人前k個數中擁有的個數,cnt3[k]表示第三個人前k個數中擁有的個數字表達式爲:
    cnt2[i]+cnt3[i]+cnt1[j]−cnt1[i]+cnt3[j]−cnt3[i]+cnt1[n]−cnt1[j]+cnt2[n]−cnt2[j]
  3. 化簡得到:
    cnt2[i]−cnt1[i]+cnt3[j]−cnt2[j]+cnt1[n]+cnt2[n]
  4. 我們從0~n枚舉i,接下來我們考慮j的取值,我們可以看到對於固定的i,只需要找到一個j使得該式子最小即可,那麼我們可以設置一個後綴minn[]數組,minn[i]表示當i≤j≤n時,cnt3[j]−cnt2[j]最小的值,那麼答案即爲:
    cnt2[i]−cnt1[i]+minn[i]+cnt1[n]+cnt2[n]

參考博客:CODEFORCES 1257E - THE CONTEST

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;

typedef long long ll;

const int N = 200010;

int n, m, k;
int num1[N];
int num2[N];
int num3[N];
int mini[N];
int a[N], b[N], c[N];

int main()
{
    scanf("%d %d %d", &n, &m, &k);
    int tot = n + m + k;
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        num1[a[i]]++;
    }
    for(int i = 1; i <= m; i++)
    {
        scanf("%d", &b[i]);
        num2[b[i]]++;
    }
    for(int i = 1; i <= k; i++)
    {
        scanf("%d", &c[i]);
        num3[c[i]]++;
    }
    for(int i = 1; i <= tot; i++)
    {
        num1[i] += num1[i - 1];
        num2[i] += num2[i - 1];
        num3[i] += num3[i - 1];
    }
    mini[tot + 1] = inf;
    for(int i = tot; i >= 0; i--)
    {
        int now = num3[i] - num2[i];
        mini[i] = min(mini[i + 1], now);
    }
    int ans = inf;
    for(int i = 0; i <= tot; i++)
    {
        int now = num2[i] - num1[i] + num1[tot] + num2[tot] + mini[i];
        ans = min(ans, now);
    }
    printf("%d\n", ans);
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章