Educational Codeforces Round 114 (Rated for Div. 2)(补题)

Posted 佐鼬Jun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Educational Codeforces Round 114 (Rated for Div. 2)(补题)相关的知识,希望对你有一定的参考价值。

D. The Strongest Build

题目链接: link.

题意:

现在给 n n n组物品栏,每组物品栏有 x x x个物品,每组物品栏里的物品的价值 w i w_i wi是单调递增的,共 x x x个物品,你只能从每组物品栏里选出 1 1 1个物品,最终选出物品价值最大的组合,现在又 m m m组物品禁止列表单,这 m m m行都描述了,你不能使用把哪些物品组合起来用,在上面这 m m m行的限制下,找到最大价值物品的组合,若有多个最大价值物品组合,输出一种即可

思路:

由于每组物品栏内部的物品从左到右的价值是单调递增的,所以物品的抉择不是杂乱无章的,而是贪心的,尽量选择右边的物品,那肯定能使物品的价值总和最大(因为每个物品的选择,对于下一个物品组的抉择没有影响,在没有禁止列表情况下),所以尽量靠右选,因此最优方案那就是选出每个物品栏里最右边的物品,那样物品价值和一定是最大,这种方案被禁止了,那就枚举这种禁止的方案,并选出禁止方案里的物品的前一个物品,看价值是否最大,即如果当前方案被禁止了,那就看这种禁止方案把其中一个物品换成前一个物品,看是否是价值最大的。
选出其中一种禁止方案,并枚举其中一种物品与前一个物品作比较时,要看进制方案里是否又这种禁止方案,如果有的话,那就不能美剧这种情况,最终选出价值最大的方案即可,在具体操作中,运用了部分STL函数的 v e c t o r vector vector函数,并用了 r e s i z e resize resize(给数组开空间),对二维数组整体二分binary_search(二分搜索),还有对二维vector整体排序sort(类似字符串排序),
(题解思路学的是官方题解的思路,此题还可以用自己建立哈希来做)

#include <bits/stdc++.h>
using namespace std;
int n, m;
vector<vector<int> > a;
vector<vector<int> > b;

int main() {
    scanf("%d", &n);
    a.resize(n);
    for (int i = 0; i < n; i++) {
        int x;
        scanf("%d", &x);
        a[i].resize(x);
        for (int j = 0; j < x; j++) {
            scanf("%d", &a[i][j]);
        }
    }
    scanf("%d", &m);
    b.resize(m);
    for (int i = 0; i < m; i++) {
        b[i].resize(n);
        for (int j = 0; j < n; j++) {
            scanf("%d", &b[i][j]);
            b[i][j]--;
        }
    }
    sort(b.begin(), b.end());
    vector<int> now(n);
    for (int i = 0; i < n; i++) {
        now[i] = (int)a[i].size() - 1;
    }
    if (!binary_search(b.begin(), b.end(), now)) {
        for (int i = 0; i < n; i++) {
            printf("%d ", now[i] + 1);
        }
        printf("\\n");
        return 0;
    }

    int Max = 0;
    vector<int> ans(n, -1);
    for (int i = 0; i < m; i++) {
        vector<int> temp = b[i];
        int sum = 0;
        for (int j = 0; j < n; j++) {
            sum += a[j][temp[j]];
        }
        for (int j = 0; j < n; j++) {
            if (temp[j] != 0) {
                temp[j]--;
                if (!binary_search(b.begin(), b.end(), temp) &&
                    sum - a[j][temp[j] + 1] + a[j][temp[j]] > Max) {
                    Max = sum - a[j][temp[j] + 1] + a[j][temp[j]];
                    ans = temp;
                }
                temp[j]++;
            }
        }
    }
    for (int i = 0; i < n; i++) {
        printf("%d ", ans[i] + 1);
    }
    return 0;
}

To be continued
如果你有任何建议或者批评和补充,请留言指出,不胜感激

以上是关于Educational Codeforces Round 114 (Rated for Div. 2)(补题)的主要内容,如果未能解决你的问题,请参考以下文章

Educational Codeforces Round 7 A

Educational Codeforces Round 7

Educational Codeforces Round 90

Educational Codeforces Round 33

Codeforces Educational Codeforces Round 54 题解

Educational Codeforces Round 27