Ordering Pizza(贪心)

在一场编程竞赛决赛中,需要为参赛者订购披萨。每份披萨包含S片,选手对不同类型的披萨有不同的满意度。目标是用最少的披萨数量满足所有选手的需求并最大化总满意度。输入包括选手的披萨需求量、类型1和类型2披萨的满意度。问题在于确定如何分配披萨类型以最大化总幸福感。通过分析,可以找到最优策略来解决这个问题。
Ordering Pizza
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

It's another Start[c]up finals, and that means there is pizza to order for the onsite contestants. There are only 2 types of pizza (obviously not, but let's just pretend for the sake of the problem), and all pizzas contain exactly S slices.

It is known that the i-th contestant will eat si slices of pizza, and gain ai happiness for each slice of type 1 pizza they eat, and bi happiness for each slice of type 2 pizza they eat. We can order any number of type 1 and type 2 pizzas, but we want to buy the minimum possible number of pizzas for all of the contestants to be able to eat their required number of slices. Given that restriction, what is the maximum possible total happiness that can be achieved?

Input

The first line of input will contain integers N and S (1 ≤ N ≤ 105, 1 ≤ S ≤ 105), the number of contestants and the number of slices per pizza, respectively. N lines follow.

The i-th such line contains integers si, ai, and bi (1 ≤ si ≤ 105, 1 ≤ ai ≤ 105, 1 ≤ bi ≤ 105), the number of slices the i-th contestant will eat, the happiness they will gain from each type 1 slice they eat, and the happiness they will gain from each type 2 slice they eat, respectively.

Output

Print the maximum total happiness that can be achieved.

Examples
Input
3 12
3 5 7
4 6 7
5 9 5
Output
84
Input
6 10
7 4 7
5 8 8
12 5 8
6 11 6
3 3 7
5 9 6
Output
314
Note

In the first example, you only need to buy one pizza. If you buy a type 1 pizza, the total happiness will be 3·5 + 4·6 + 5·9 = 84, and if you buy a type 2 pizza, the total happiness will be 3·7 + 4·7 + 5·5 = 74.

题目大意:

懒得说了;

题目思路:
我们很容易想到如果某一个参赛者a>b就选第一个,否则就选第二个,但是这样连样例都过不去,可能很多人就会放弃这个想法,我也是,其实就是题写的不够多,这题就是顺着这个思路想下去,我们可以发现对于该选第一个的部分,能刚好整除s的部分那肯定是选第一个的,该选第二个的同理,该考虑的是余下的部分,如果余下的部分大于s,的话自然还需要两个,这样刚好可以分给两种选择一人一个,如果小于等于s,那证明只能再买一个,那说明两种选择中必须更改一种选择,这样的话,我们就去按照替换后价值损失最小排序,两种选择中选出一种最小的就行

ac代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<sstream>
#include<map>
#include<vector>
#define LL long long
#define INF 0x3f3f3f3f
#define LLINF 0x3f3f3f3f3f3f3f
using namespace std;
vector<pair<LL,LL> >V1,V2;
int n,s;
int main()
{
    while(~scanf("%d%d",&n,&s))
    {
        V1.clear();
        V2.clear();
        LL sum1 = 0;
        LL sum2 = 0;
        LL ans = 0;
        for(int i = 0;i<n;i++){
            LL a,b,c;
            scanf("%lld%lld%lld",&c,&a,&b);
            if(a>b){
                sum1 += c;
                ans += c*a;
                V1.push_back(make_pair(a-b,c));
            }
            else{
                sum2 += c;
                ans += c*b;
                V2.push_back(make_pair(b-a,c));
            }
        }
        sum1 %= s;
        sum2 %= s;
        if(sum1+sum2>s){
            cout<<ans<<endl;
            continue;
        }
        else{
            sort(V1.begin(),V1.end());
            sort(V2.begin(),V2.end());
            LL tmp1 = 0;
            LL tmp2  = 0;
            int len = V1.size();
            for(int i = 0;i<len;i++){
                tmp1 += min(sum1,V1[i].second)*V1[i].first;
                sum1 -= min(sum1,V1[i].second);
            }
            len = V2.size();
            for(int i = 0;i<len;i++){
                tmp2 += min(sum2,V2[i].second)*V2[i].first;
                sum2 -= min(sum2,V2[i].second);
            }
            cout<<ans-min(tmp1,tmp2)<<endl;
        }

    }
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值