题目链接:点击进入
题目
题意
n 个汉堡,m 个锅,每个汉堡都有做熟所需时间 t i t_i ti,一个汉堡可以在一个锅上做,也可以分两次在两个锅上做,一个锅每刻只能做一个汉堡,一个汉堡每刻只能在一个锅上。求一个汉堡放置方案,使所有汉堡做好所需时间最少( 这个所需时间,应该是所有汉堡都做完的那一刻时间 )
思路
我们求出锅的最大时间限制是多少,应该是 max ( n 个汉堡中的最长时间 ,n 个汉堡平均时间 ),我们知道一个锅最大时间是多少,剩下的就是贪心的放置汉堡,如果锅里放得下一整个汉堡,就放置,如果放不下,那就尽量放,这个汉堡剩下的那部分时间放到另一个新的锅里,重复过程,直到所有汉堡都放置结束。这样放置汉堡,一个汉堡的时间不会存在交集。因为 ti <= max,就算一个汉堡放到两个锅里,因为前半部分在锅后程,后半部分在锅前程,因此不会存在交集 ( 这里放置类似栈 )。
代码
//#pragma GCC optimize(3)//O3
//#pragma GCC optimize(2)//O2
#include<iostream>
#include<string>
#include<map>
#include<set>
//#include<unordered_map>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<stack>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<fstream>
#define X first
#define Y second
#define best 131
#define INF 0x3f3f3f3f3f3f3f3f
#define pii pair<int,int>
#define lowbit(x) x & -x
#define inf 0x3f3f3f3f
#define int long long
//#define double long double
//#define rep(i,x,y) for(register int i = x; i <= y;++i)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const double pai=acos(-1.0);
const int maxn=1e6+10;
const int mod=998244353;
const double eps=1e-9;
const int N=5e3+10;
/*--------------------------------------------*/
inline int read()
{
int k = 0, f = 1 ;
char c = getchar() ;
while(!isdigit(c)){if(c == '-') f = -1 ;c = getchar() ;}
while(isdigit(c)) k = (k << 1) + (k << 3) + c - 48 ,c = getchar() ;
return k * f ;
}
/*--------------------------------------------*/
int n,m,t[maxn],sum,maxx,maxt;
struct node
{
int pos;
int x;
}p[maxn];
struct Node
{
int l;
int r;
int pos;
};
bool cmp(node e,node f)
{
return e.x>f.x;
}
vector<Node>v[maxn];
signed main()
{
// ios::sync_with_stdio(false);
// cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>t[i],sum+=t[i],maxt=max(maxt,t[i]);
for(int i=1;i<=n;i++) p[i].pos=i,p[i].x=t[i];
if(sum%m==0) maxx=sum/m;
else maxx=sum/m+1;
maxx=max(maxx,maxt);
//sort(p+1,p+n+1,cmp);
int pos1=m,pos2=1;
while(pos1>=1&&pos2<=n)
{
if(p[pos2].x==maxx)
{
v[p[pos2].pos].push_back({0,maxx,pos1});
pos2++;
pos1--;
}
else
{
int tmp=0;
while(pos2<=n&&tmp+p[pos2].x<=maxx)
{
tmp+=p[pos2].x;
v[p[pos2].pos].push_back({tmp-p[pos2].x,tmp,pos1});
pos2++;
}
if(pos2<=n&&tmp!=maxx)
{
p[pos2].x-=(maxx-tmp);
v[p[pos2].pos].push_back({tmp,maxx,pos1});
}
pos1--;
}
}
for(int i=1;i<=n;i++)
{
cout<<v[i].size()<<" ";
for(int j=v[i].size()-1;j>=0;j--)
cout<<v[i][j].pos<<" "<<v[i][j].l<<" "<<v[i][j].r<<" ";
cout<<endl;
}
return 0;
}