Codeforces 1257E - The Contest

题意
三个人,每个人有一些数字,组合起来是\(1\)~\(n\),每个人可以给另一个人一个拥有的数字,问最小操作数,使得第一个人拥有\(1\)~\(i\)的数,第二个人拥有\(i+1\)~\(j\)的数,第三个人拥有\(j+1\)~\(n\)的数,即第一个人为前缀,第二个人为中间部分,第三个人为后缀。
注意:可以有一个或两个人最后不拥有数字。

分析
看到三个人操作,我们先看两个人操作时的情况:
假设到最后,第一个人拥有\(1\)~\(i\),第二个人拥有\(i+1\)~\(n\),那么最小操作数为第二个人\(1\)~\(i\)中中拥有的数字加上第一个人\(i+1\)~\(n\)中拥有的数字。我们可以采用前缀和,\(cnt1[k]\)表示第一个人前\(k\)个数中拥有的个数,\(cnt2[k]\)表示第二个人前\(k\)个数中拥有的个数,则表达式为:\[cnt2[i]+cnt1[n]-cnt1[i]\]受到启发我们看三个人操作时的情况:
假设到最后,第一个人拥有\(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]\]化简得到:\[cnt2[i]-cnt1[i]+cnt3[j]-cnt2[j]+cnt1[n]+cnt2[n]\]我们从\(0\)~\(n\)枚举\(i\),接下来我们考虑\(j\)的取值,我们可以看到对于固定的\(i\),只需要找到一个\(j\)使得该式子最小即可,那么我们可以设置一个后缀\(minn[]\)数组,\(minn[i]\)表示当\(i\leq j\leq n\)时,\(cnt3[j]-cnt2[j]\)最小的值,那么答案即为:\[cnt2[i]-cnt1[i]+minn[i]+cnt1[n]+cnt2[n]\]
代码

#pragma GCC optimize(3, "Ofast", "inline")

#include <bits/stdc++.h>

#define start ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define LL long long
using namespace std;
const int maxn = (ll) 2e5 + 5;
const int mod = 1000000007;
const int inf = 0x3f3f3f3f;
int cnt1[maxn], cnt2[maxn], cnt3[maxn];
int minn[maxn];
vector<int> v1, v2, v3;

int main() {
    start;
    int k1, k2, k3;
    cin >> k1 >> k2 >> k3;
    v1.resize(k1 + 5);
    v2.resize(k2 + 5);
    v3.resize(k3 + 5);
    /*输入并标记*/
    for (int i = 1; i <= k1; ++i) {
        cin >> v1[i];
        ++cnt1[v1[i]];
    }
    for (int i = 1; i <= k2; ++i) {
        cin >> v2[i];
        ++cnt2[v2[i]];
    }
    for (int i = 1; i <= k3; ++i) {
        cin >> v3[i];
        ++cnt3[v3[i]];
    }
    int n = k1 + k2 + k3;
    for (int i = 1; i <= n; ++i) {//前缀和
        cnt1[i] = cnt1[i - 1] + cnt1[i];
        cnt2[i] = cnt2[i - 1] + cnt2[i];
        cnt3[i] = cnt3[i - 1] + cnt3[i];
    }
    /*如分析*/
    for (int i = 0; i <= n; ++i)
        minn[i] = cnt3[i] - cnt2[i];
    for (int i = n - 1; i >= 0; --i)
        minn[i] = min(minn[i + 1], minn[i]);
    int ans = inf;
    for (int i = 0; i <= n; ++i) {
        int t = cnt2[i] - cnt1[i] + minn[i] + cnt1[n] + cnt2[n];
        ans = min(ans, t);
    }
    cout << ans;
    return 0;
}

本场比赛\(D\)和\(E\)惨痛教训:玩后缀一定要注意边界!!!
若有问题可在评论区提出,谢谢。

原文地址:https://www.cnblogs.com/F-Mu/p/11857186.html

时间: 2024-10-08 14:51:20

Codeforces 1257E - The Contest的相关文章

[Codeforces 1295F]Good Contest(DP+组合数学)

[Codeforces 1295F]Good Contest(DP+组合数学) 题面 有一个长度为\(n\)的整数序列,第\(i\)个数的值在\([l_i,r_i]\)中随机产生.问这个序列是一个不上升序列的概率(模\(998244353\)意义下). \(n \leq 50,l_i,r_i \leq 998244351\) 分析 和[APIO2016]划艇几乎一模一样.可惜比赛的时候时间不够. 首先把问题转化成求最长不上升序列的数量. 我们把这些区间离散化,分割成两两之间不互相覆盖的若干个区间

http://codeforces.com/contest/575/problem/B

题目链接: http://codeforces.com/contest/575/problem/B 题解: 代码: #include<cstdio> #include<vector> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn = 1e5 + 10; const int DEG = 22; const in

http://codeforces.com/contest/741/problem/B B. Arpa&#39;s weak amphitheater and Mehrdad&#39;s valuable Hoses

题意: 给出上限体重W 然后还给出每个人的体重wi 和 魅力值 bi 互为伙伴的对(xi, yi) 可以凑成group 思路: 并查集找出所有的group 暴力背包 对于每一个group 要选出这一组内选一个人时的最优结果, 如果所有人的体重和小于等于W,还得考虑选所有人的情况 #include <iostream> #include <string.h> #include <algorithm> #include <stdio.h> #include &l

http://codeforces.com/contest/349

A. Cinema Line time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output The new "Die Hard" movie has just been released! There are n people at the cinema box office standing in a huge line. Ea

CodeForces B. Creating the Contest

http://codeforces.com/contest/1029/problem/B You are given a problemset consisting of nn problems. The difficulty of the ii-th problem is aiai. It is guaranteed that all difficulties are distinct and are given in the increasing order. You have to ass

【Codeforces:从头开始】contest 1

[Codeforces:从头开始]contest 1      1A      用 a × a 的石板覆盖 n × m 的长方形广场,允许石板覆盖的区域超出广场,不允许打破石板,石板的两侧应平行于广场两侧,要求覆盖完广场所需的石板数量最少是多少 样例图示: (显然,答案为每边必须铺的+铺出去(1个或0个)) 注意开 long long 代码: #include<bits/stdc++.h> using namespace std; typedef long double ld; typedef

Educational Codeforces Round 76 (Rated for Div. 2) E. The Contest

Educational Codeforces Round 76 (Rated for Div. 2) E. The Contest(dp+线段树) 题目链接 题意: 给定3个人互不相同的多个数字,可以把数字移动给别人,问最少移动几次后可以使第一个人的数字为1~m1,第二个人m1~m2,第三个人m2~n(可以没有数字) 题解: 设c[1][i]为第一个人m1为i时需要移动的次数,c[3][i]为m2为i是第三个人需要操作的次数,当其他两个人数字合法时,第二个人的数字也会合法.枚举第一个人的每个i,

Codeforces Round #604 (Div. 2) C. Beautiful Regional Contest

链接: https://codeforces.com/contest/1265/problem/C 题意: So the Beautiful Regional Contest (BeRC) has come to an end! n students took part in the contest. The final standings are already known: the participant in the i-th place solved pi problems. Since

CodeForces 659 B. Qualifying Contest(结构体排序的问题)

传送门 B. Qualifying Contest time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard output Very soon Berland will hold a School Team Programming Olympiad. From each of the m Berland regions a team of two people