Codeforces Round #437 (Div. 2) C. Ordering Pizza (贪心)

原题地址:http://codeforces.com/contest/867/problem/C

题意:有两种披萨,给你n个人和他们要吃多少片披萨,和他们分别吃到两种披萨的满足度,在给你一个披萨有s片,让你求:

前提是买最少的披萨,可以获得的最大满足度。

思路:首先假设没有最小披萨的限制,那么最优解就是每一个人吃1号披萨和2号披萨中取一个较大的值乘上他所要吃的披萨数.但是现在由于有了最小披萨的限制,我们分别一个人更喜欢吃1号披萨还是2号披萨的数量len1和len2,最后如果len1%s+len2%s是大于一个披萨的话,结果就是不受影响的.但是如果少于s,那就说明肯定有一些更喜欢1号的披萨的人要吃2号披萨,或者喜欢2号披萨的人要去吃1号披萨.因此,对于这种情况,分别比较取一个减少小的就行了.开一个结构体记录去吃不喜欢的披萨所要减少的高兴值.

#include <bits/stdc++.h>
#include <cmath>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <set>
#include <map>
#include <cctype>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define CLR(x,y) memset((x),y,sizeof(x))
#define fuck(x) cerr << #x << "=" << x << endl

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int seed = 131;
const int maxn = 1e5 + 5;
const int mod = 998244353;
int n, s;
struct node {
    ll num, cha;
    bool operator <(const node &a)const {
        return cha < a.cha;
    }
};
vector<node>a, b;
int main() {
    scanf("%d%d", &n, &s);
    ll numa = 0, numb = 0;
    ll ans = 0;
    for (int i = 1; i <= n; i++) {
        ll s, x, y;
        scanf("%I64d%I64d%I64d", &s, &x, &y);
        if (x >= y) {
            node p;
            p.num = s;
            p.cha = x - y;
            numa += s;
            ans += s * x;
            a.push_back(p);
        } else {
            node p;
            p.cha = y - x;
            p.num = s;
            numb += s;
            ans +=s * y;
            b.push_back(p);
        }
    }
    numa %= s;
    numb %= s;
    if (numa + numb > s) printf("%I64d\n", ans);
    else {
      ll sum1 = 0;
        sort(a.begin(), a.end());
        sort(b.begin(), b.end());
        for (int i = 0; i < a.size(); i++) {//分别考虑a,b
            if (numa == 0) break;
            if (a[i].num <= numa) {
                numa -= a[i].num;
                sum1 += a[i].num * a[i].cha;
            } else {
                sum1 += numa * a[i].cha;
                numa = 0;
            }
        }
        ll sum2 = 0;
        for (int i = 0; i < b.size(); i++) {
            if (numb == 0) break;
            if (b[i].num <= numb) {
                numb -= b[i].num;
                sum2 += b[i].num * b[i].cha;
            } else {
                sum2 += numb * b[i].cha;
                numb = 0;
            }
        }
        printf("%I64d\n", ans - min(sum1, sum2));//取一个小值
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yiqzq/article/details/81710133