题目描述
输入描述
输出描述
输入样例
5 3
1 2 3 4 5
输出样例
1 1 0 1
1 2 0 2
1 2 2 5
1 1 1 5
1 3 0 5
样例说明
题目大意:给定 n 块牛排及它们分别需要烹饪的时间 ti 和 m 个锅,每块牛排最多只能在两个锅上烹饪,且一个锅不能同时烹饪两块牛排,一块牛排也不能同时在两个锅上烹饪,求所有牛排煮熟所需要的最小时间。
阅读题意后不难得出,每个锅的使用时间上限为 max ( 每块牛排烹饪时间总和 / 锅的个数,单块牛排所需最大烹饪时间 ),因此可以考虑用样例说明中的思路,按顺序遍历牛排并优先将每个锅的使用时间填满。
如果当前牛排所需的烹饪时间大于当前锅的剩余使用时间时,可先将该锅剩余时间填满,并更新该牛排仍需的烹饪时间。由于每块牛排只能在两个锅上烹饪,因此需找到下一个锅满足:剩余使用时间足够烹饪完该牛排且结束的时间不大于前一个锅的开始时间。
参考代码
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef long long ll;
typedef pair<ll,ll> pii;
pii a[N];
ll t[N];
ll p[N];
int main(){
ll n,m,pan1=1,pan2,ta1,ta2,tb1,tb2,sign;//pan:前pan-1的盘子已满不用考虑
memset(p,0,sizeof(p));
ll sum=0;
cin>>n>>m;
for(ll i=1;i<=n;i++){
cin>>t[i];
sum+=t[i];
a[i]=pii(t[i],i);
}
ll ave=sum/m;
if(sum%m!=0)
ave++;
sort(a+1,a+n+1);
if(a[n].first>ave)
ave=a[n].first;
for(ll i=1;i<=n;i++){
if(t[i]+p[pan1]>ave){
ta1=p[pan1],ta2=ave;
cout<<'2'<<' ';
t[i]=t[i]-ave+p[pan1];
sign=pan1;
pan1++;
pan2=pan1;
while(p[pan2]+t[i]>ave||p[pan2]+t[i]>ta1)
pan2++;
tb1=p[pan2];
p[pan2]+=t[i];
tb2=p[pan2];
cout<<pan2<<' '<<tb1<<' '<<tb2<<' '<<sign<<' '<<ta1<<' '<<ta2<<endl;
}
else{
cout<<'1'<<' '<<pan1<<' '<<p[pan1]<<' ';
p[pan1]+=t[i];
cout<<p[pan1]<<endl;
}
if(p[pan1]==ave)
pan1++;
}
return 0;
}