题目链接:传送门
题目描述
ICPC manager plans a new project which is to be carried out for n days. In this project, m persons numbered from 1 to m are supposed to work. Each day j (1 ≤ j ≤ n) requires dj persons, and each person i (1 ≤ i ≤ m) wants to work wi days.
To increase the efficiency in performing the project, the following two conditions should be satisfied:
1.each person works for only consecutive w days when he/she works, and
2.each person can work again after he/she has a rest for at least h days.
ICPC manager wants to find a working plan to assign the working days for all persons such that the number of working days of each person i (1 ≤ i ≤ m) is equal to wi and the number of persons who work for each day j (1 ≤ j ≤ n) is equal to dj, and above two conditions are also satisfied.
For example, assume the project is carried out for n = 9 days, and m = 4 persons participate in the project. Let w = 2 and h = 1. Also, assume (w1, w2, w3, w4) = (4, 4, 6, 2) and (d1, d2, d3, d4, d5, d6, d7, d8, d9) = (1, 3, 2, 1, 2, 1, 1, 3, 2). The table below shows a feasible solution where the i-th row corresponds to person i, and the j-th column corresponds to day j. If person i works or has a rest in day j, the value of the table element with row i and column j is 1 or 0, respectively.
Given m, n, w, h, wi (1 ≤ i ≤ m) which is a multiple of w, and dj (1 ≤ j ≤ n), write a program to find a feasible solution as a working plan.
输入
Your program is to read from standard input. The input starts with a line containing four integers, m, n, w, h (1 ≤ m ≤ 2,000, 1 ≤ n ≤ 2,000, 1 ≤ w, h ≤ n). The following line contains m integers where the i-th (1 ≤ i ≤ m) integer represents wi (1 ≤ wi ≤ n) which is a multiple of w. The next line contains n integers where the j-th (1 ≤ j ≤ n) integer represents dj (0 ≤ dj ≤ m).
输出
Your program is to write to standard output. If there is a feasible working plan, print 1 in the first line followed by m lines, each i-th (1 ≤ i ≤ m) line should contain wi/w integers. These integers form an increasing sequence of first days that person i works in the feasible plan. If there is no feasible working plan, print only -1 in the first line. The first sample below corresponds to the example given in the table above.
样例输入
样例数据
4 9 2 1 4 4 6 2 1 3 2 1 2 1 1 3 2
样例输出
1 1 8 2 7 2 5 8 4
【题意】:
有n天,m个工人,他们一旦工作就要连续工作w天,然后需要休息h天。
然后每个工人需要工作wi天,其中这个wi天是需要能被w天整除的。
最后是n天,每一天需要的工人数目。
【题解】:
其实贪心的题目写博客真的没有什么意思,但是这个题目非常具有代表性,这个题目就是代表着我们的操作系统中,进程调度,这一个环节。贪心进行即可。
把所有需要的人数的天数单独处理,用vis[i],表示,即第i天需要的工人数,因为题目给的那些是工人数,但是实际上每个工人都是连续工作多少天的,我们可以预处理这个数组出来。
处理完了,我们就知道1~n天每一天真正需要的人数对吧。
然后我们需要设立两个优先队列,
一个优先队列叫做 就绪队列Q,就是里面都是空闲的工人。
另外的一个优先队列叫做:阻塞队列tQ,里面都是已经派出去工作的工人,但是他们需要到某一个时间回来。
这个就是完整的一个进程调度的过程,看吧!!!
我们就是贪心处理,我们让就绪队列Q,按照工人的需要工作的天数排序,工作天数越大的排前面。
相对地,阻塞队列tQ,就需要按照工人回来下一次工作的时间进行排序。
然后我们就可以写出这个代码了
#include <stdio.h>
#include <string.h>
#include <map>
#include <algorithm>
#include <math.h>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
typedef long long ll;
const int N = 5e6+10;
const ll mod = 998244353;
const double eps = 1e-7;
int a[N],b[N],c[N],d[N],vis[N];
typedef struct Node{
int No,val,t;
}Node;
typedef struct Cmp1{
bool operator () (const Node &u,const Node &v)const {
return u.t > v.t;
}
}Cmp1;
typedef struct Cmp2{
bool operator () (const Node &u,const Node &v)const {
return u.val < v.val;
}
}Cmp2;
Node w[N];
vector<int>v[2020];
int main()
{
int n,m,h,W;
scanf("%d%d%d%d",&m,&n,&W,&h);
priority_queue <Node,vector<Node> ,Cmp2> Q;
priority_queue <Node,vector<Node> ,Cmp1> tQ;
for(int i=1;i<=m;i++){
scanf("%d",&b[i]);
w[i].No = i;
w[i].val = b[i]/W;
w[i].t = 0;
Q.push(w[i]);
}
/*while(!Q.empty()){
Node t = Q.top();
Q.pop();
printf("%d %d\n",t.No,t.val);
}*/
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
int cnt = 0 ,flag=1;
for(int i=1;i<=n;i++){
if(a[i]!=0){
int t=a[i];
for(int j=1;j<=a[i];j++){
//vis[i]++;
d[cnt++] = i;
}
vis[ i ]+=a[i];
for(int j=i;j<=i+W-1;j++)
a[j]-=t;
}
}
/*
for(int i=0;i<cnt;i++){
printf("%d%c",d[i],i==cnt-1?'\n':' ');
}
for(int i=1;i<=n;i++){
printf("%d%c",vis[i],i==n?'\n':' ');
}*/
Node cur;
for(int i=1;i<=n;i++){
while( !tQ.empty() ){
cur = tQ.top();
if ( cur.t <= i ){
Q.push(cur);
tQ.pop();
}else{
break;
}
}
while( !Q.empty() && vis[i] ){
cur = Q.top();
Q.pop();
vis[i]--;
cur.t = i + W + h;
cur.val -- ;
v[cur.No].push_back(i);
if(cur.val!=0)
tQ.push(cur);
}
if(vis[i]){
flag=0;break;
}
}
if(!flag){
printf("-1\n");
}else{
printf("1\n");
for(int i=1;i<=m;i++){
int sz = v[i].size();
int cnt =0;
for(auto j :v[i]){
cnt++;
printf("%d%c",j,cnt==sz?'\n':' ');
}
}
}
return 0;
}
/*
4 14 3 2
9 6 9 6
2 3 3 2 1 2 2 2 1 2 3 4 2 1
*/