有两种披萨,给你n个人和他们要吃多少片披萨,和他们分别吃到两种披萨的满足度,在给你一个披萨有s片,让你求:
前提是买最少的披萨,可以获得的最大满足度。
POINT:
贪心,每个人总会比较喜欢吃某一个披萨,记录下来,记录a披萨有几个人喜欢吃的总片数ca,b披萨也一样cb。
ans+=num*max(aa,bb);
那么可以贪心的给他们吃披萨,就会剩下来ca%s个人喜欢吃a披萨,cb%s个人喜欢吃b披萨。
如果这剩下来的总和大于s,说明一块披萨满足不了,那么给他们各自喜欢的,答案就是ans。
如果小于等于s,说明必须有一边的人要不吃他喜欢的披萨,那么就讨论一下,如果ca%s个人吃b披萨会减少多少满足度,
如果cb%s个人吃a披萨会减少多少满足度,取一个较小值,ans-=他 就行了。
所以我们要记录的是,喜欢吃a的差值和对应的片数,b也一样。差值从小到大排序。
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
#define LL long long
const LL maxn = 100100;
struct node
{
LL num,cha;
node(LL n,LL c):
num(n),cha(c){}
};
vector<node>a,b;
bool cmd(node aa,node bb)
{
return aa.cha<bb.cha;
}
int main()
{
LL n,s;
scanf("%lld %lld",&n,&s);
LL numa=0,numb=0;
LL ans=0;
for(LL i=1;i<=n;i++){
LL num,aa,bb;
scanf("%lld %lld %lld",&num,&aa,&bb);
if(aa>=bb){
a.push_back(node(num,aa-bb));
numa+=num;
ans+=aa*num;
}else{
b.push_back(node(num,bb-aa));
numb+=num;
ans+=bb*num;
}
}
numa%=s;
numb%=s;
if(numa+numb>s){
printf("%lld\n",ans);
return 0;
}
LL ansa=0;
sort(a.begin(),a.end(),cmd);
for(LL i=0;i<a.size();i++){
if(numa==0) break;
else if(numa>=a[i].num){
ansa+=a[i].num*a[i].cha;
numa-=a[i].num;
}
else{
ansa+=numa*a[i].cha;
numa=0;
}
}
LL ansb=0;
sort(b.begin(),b.end(),cmd);
for(LL i=0;i<b.size();i++){
if(numb==0) break;
else if(numb>=b[i].num){
ansb+=b[i].num*b[i].cha;
numb-=b[i].num;
}
else{
ansb+=numb*b[i].cha;
numb=0;
}
}
ans-=min(ansb,ansa);
printf("%lld\n",ans);
}