Hamburger Steak
题意:
有m个锅,n块肉,每个肉需要煎ai分钟才能熟,每个锅同时最多煎一块肉,一块肉最多可以被两个锅煎(但不能同时),问最少多长时间能全部煎熟,并输出方案
题解:
我一开始的想法是:二分每个锅最长用的时间,然后顺序煎每个肉,如果这个肉还没煎完,这个锅的时间用完了,就到下一个锅继续煎,顺序输出完事。需要保证所有锅的时间和大于等于所有肉需要的时间
后来发现其实最小耗时不用二分,直接算出来的T=max{max{ti},|∑ti\sum{ti}∑ti/m|},
代码:
#include<bits/stdc++.h>
#define debug(a,b) printf("%s = %d\n",a,b);
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
//Fe~Jozky
const ll INF_ll=1e18;
const int INF_int=0x3f3f3f3f;
inline ll read(){ll s=0,w=1ll;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')w=-1ll;ch=getchar();}while(ch>='0'&&ch<='9') s=s*10ll+((ch-'0')*1ll),ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);return s*w;
}
void rd_txt(){#ifdef ONLINE_JUDGE#elsefreopen("in.txt","r",stdin);#endif
}
int n,m;
const int maxn=3e5+9;
ll a[maxn];
bool check(ll x){ll sum=0; ll tot=1;for(int i=1;i<=n;i++){sum+=a[i];if(sum>x){tot++;sum=sum-x;}}if(tot>m)return 0;return 1;
}int main()
{rd_txt();cin>>n>>m;ll l=0,r=0;for(int i=1;i<=n;i++){cin>>a[i];l=max(a[i],l);r+=a[i];}r=r*2;while(l<r){ll mid=l+r>>1;if(check(mid))r=mid;else l=mid+1;}//cout<<"l="<<l<<endl;ll sum=0;ll tot=1;ll L=0;for(int i=1;i<=n;i++){if(L+a[i]>l){printf("2 %lld %lld %lld %lld %lld %lld\n",tot+1,0,L+a[i]-l,tot,L,l);tot++;L=L+a[i]-l;}else {printf("1 %lld %lld %lld\n",tot,L,L+a[i]);L+=a[i];}if(L==l){L=0;tot++;}}
}