Working Plan

题目链接

题目图片:

 

 

用到的知识点:

1.优先队列与内嵌比较函数的结合

2.队列的stl库的调用

3.vector容器

难点解答:

1.

2. push-back()

3. 内嵌比较函数:

4. 

题目大致思路:

 1.把需要的每天的人数d[i]数组预处理为第i天刚开始工作的人数。

2.两个队列,一个工作队列q,一个休息队列q1。

3.本题采用了贪心的思想,每次都先选工作时间最长的那个人。

4.寻找的时候两个循环:

代码如下:

#include<bits/stdc++.h>
using namespace std;
#define maxn 2019
int W[maxn],d[maxn];
vector<int>v[maxn];
struct node
{
    int id,cnt,next;
    node(int x,int y,int z)
    {
        id=x;
        cnt=y;
        next=z;
    }
    bool operator <(const node& r)const
    {
        return cnt<r.cnt;
    }//优先队列是从大到小排序,q.top(),输出的是最大值
//但是这只是针对单个类型int而言
//本题需要对结构体中的cnt由大到小进行排序,并且输出最大的
//因此用到了结构体内嵌比较函数,cnt<r.cnt,表示先输出cnt大的。
};
int main()
{
    int m,n,w,h;
    cin>>m>>n>>w>>h;
    for(int i=1; i<=m; i++)
    {
        cin>>W[i];
    }
    d[0]=0;
    for(int i=1; i<=n; i++)
    {
        cin>>d[i];
    }
    priority_queue<node>q;
    queue<node>q1;
    for(int i=1; i<=n; i++)
    {
        for(int j=i+1; j<=i+w-1; j++)
        {
            d[j]-=d[i];
        }
    }//原来的d[i]数组是用来记录每一天需要用多少人的
    //现在把它预处理成有几个人需要在第i天开始工作
    for(int i=1; i<=m; i++)
    {
        q.push(node(i,W[i],1));//这里的1也可以写成0,2等,不影响
        //就是进行一下初始化
    }
    int f=1;
    for(int i=1; i<=n; i++)
    {
        while(q1.size()&&q1.front().next==i)
        {
            node now=q1.front();
            q.push(now);
            q1.pop();
        }
        while(d[i]--)
        {
            if(q.size()==0)
            {
                f=0;
                break;
            }
            node now=q.top();
            q.pop();
            if(i+w-1>n)
            {
                f=0;
                break;
            }//如果它没有满足连续的工作时间
            v[now.id].push_back(i);
            now.next=i+w+h;
            now.cnt-=w;
            if(now.cnt!=0)
                q1.push(now);
        }
    }
    if(f)
    {
        cout<<1<<endl;
        int i,j;
        for(i=1; i<=m; i++)
        {
            int len=v[i].size();
            for(j=0; j<len-1; j++)
            {
                cout<<v[i][j]<<" ";
            }
            cout<<v[i][j];
            cout<<endl;
        }
    }
    else
        cout<<-1<<endl;

    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值