牛客多校6 Hamburger Steak 贪心

Hamburger Steak

题目描述

Riko is ready to cook hamburger steaks. There are m pans and n hamburger steaks that need to be fried. The iii-th hamburger steak needs to be fried for ti​ (which is a positive integer) minutes. Riko can fry it in a certain pan for ti​ minutes, or in two different pans for ai and biminutes respectively, where ai​ and bi​ are both positive integers and ai+bi=ti​. Riko will start cooking at time 0 and she wants to finish cooking as soon as possible. Please help Riko make a plan to minimize the time spent cooking all the hamburger steaks.

In this problem, we assume that a pan can fry at most one hamburger steak at the same time, and a hamburger steak can be put in at most one pan at the same time. Different pans can fry different hamburger steaks at the same time. We also assume that it takes no time to put a hamburger steak in a pan or take it out.

输入描述:

 

The first line of the input contains two integers n and m (1≤n,m≤10^5)

The second line contains n integers t1,t2,…,tn (1≤ti≤10^9)

输出描述:

 

Output n lines. The i-th line describes the cooking plan for the i-th hamburger steak.

Each line begins with an integer k (k∈{1,2}), representing that Riko will fry the hamburger steak in k pans. Then there follow kinteger triples id,l,r (1≤id≤m, 0≤l<r≤10^18)i in chronological order, representing that Riko will fry the hamburger steak in the pan numbered ididid during time [l,r)

If there are multiple answers, output any.

示例1

输入

5 3
1 2 3 4 5

输出

1 1 0 1

类型:贪心。

题意:给出n个ham和m个锅,每个ham都有所需烹饪时间ti,一个锅只能同时烹饪一个ham,一个ham可以依次在几个锅里烹饪,但是不能同时在两个锅里烹饪。求出使烹饪时间最短的烹饪策略。

思路:key:首先求出最小烹饪时间.因为锅的数量可能比ham的数量少,所以最大值ma可能并不是ti中的最大值,也有可能是sum/m向上取整,sum为ham烹饪时间之和,只需要在两个之中取最大值即可。设当前锅剩余烹饪时间为t,最初,对于每个锅,剩余烹饪时间都是最大值ma.然后开始遍历每个ham,如果所需时间ti<=t,那么就使用这一个锅就可,开始时间为sum-t,结束时间为sum-t+t[i],并且更新此锅剩余时间t-=t[i],此时如果剩余时间为0了,那么就换下一个锅了。

如果当前锅的剩余烹饪时间t<a[i],那么先使用此锅剩余烹饪时间烹饪,之后再在下一个新锅里烹饪。

代码如下

#include <bits/stdc++.h>
using namespace std;
#define N 100010
typedef long long ll;
ll a[N],sum,ma;
int n,m;
int main(){
	cin>>n>>m;
	for(int i=0;i<n;i++){
		cin>>a[i];
		sum+=a[i];
		ma=max(ma,a[i]);
	}
	sum=max(ma,sum/m+(sum%m!=0));//最长时间
	ll t=sum,id=1;//id为锅的编号,t为每个锅所剩时间,初始都为最大值 
	for(int i=0;i<n;i++){
		if(t>=a[i]){//如果这个锅所剩的时间够能一次性烹饪, 
			cout<<1<<" "<<id<<" "<<sum-t<<" "<<sum-t+a[i]<<endl;
			//因为前面可能已经烹饪过了,所以开始时间应该是sum-t,结束时间等于开始时间+所花时间 
			t-=a[i];//此锅剩余烹饪时间减少a[i] 
			if(!t){//如果烹饪完这一ham过后此锅剩余时间为0 
				id++;//那么就换下一个锅 
				t=sum;//下一个锅起始剩余时间为sum 
			}
		}
		else{
			//当此锅够一次性烹饪时,结束时间总是为开始时间+所需时间。 
			/*使用两个锅烹饪,那么就先把这个还有剩余时间但是不够一次性烹饪的锅使用了,此锅消耗时间t
			剩余还需a[i]-t在下一个新锅里烹饪,开始时间:0,所需时间:a[i]-t 
			*/
			cout<<2<<" "<<id+1<<" "<<0<<" "<<a[i]-t<<" "<<id<<" "<<sum-t<<" "<<sum<<endl;
			id++;//此锅已无剩余时间,换下一个锅啦! 
			t=sum-(a[i]-t);//下一个锅的剩余时间为sum-(a[i]-t); 
		}
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值