Codeforces Round #133 (Div. 2) C. Hiring Staff 想法题目

http://codeforces.com/problemset/problem/216/C

题意:

在Berland法律规定每个工人的工作是这样的:它必须连续工作n天,然后休息m天,然后才能继续工作n天休息m天也即他的工作时间为[x, x + 1, ..., x + n - 1][x + m + n, x + m + n + 1, ..., x + m + 2n - 1] Vitaly的工场必须保证每天有k个工人,而且还要保证在第n天时,有员工能够接任工厂钥匙。Vitaly想尽量少的雇用工人,以减少花费。求他最少雇用员工的个数以及他们分别在第几天雇用。

思路:

自己开了虚拟比赛做的题目,好不容易把A,B做完了来整这道题,分析了很久,云里雾里脑子乱的很。所以就没推出来,赛后看了官方的解体报告。觉得这种想法太好了。自己脑子还是比较笨。

The second solution: greedy.
Let's create an array where we will store current number of employees for some number of the first days. Now you should iterate over all days from the first to the n + m-th and hire employees every time when it needed. You should hire workers if there are less than kpeople in the current day; also you should hire worker if there will be no people tomorrow (thet worker will bring the key to the workers that will work tomorrow).
This solution works in O((n + m)k).
This solution also works correctly for cases n < m, but then it has bigger complexity and requires more time.

 

View Code
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <string>

#define CL(a,num) memset((a),(num),sizeof(a))
#define iabs(x)  ((x) > 0 ? (x) : -(x))
#define Min(a,b) (a) > (b)? (b):(a)
#define Max(a,b) (a) > (b)? (a):(b)

#define ll long long
#define inf 0x7f7f7f7f
#define MOD 1073741824
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)
#define test puts("<------------------->")
#define maxn 100007
#define M 1000007
#define N 20007
using namespace std;
//freopen("data.in","r",stdin);

int use[N];
vector<int>vi;
int main(){
   // freopen("data.in","r",stdin);
   int n,m,k;
   int i,j;
   while (~scanf("%d%d%d",&n,&m,&k)){
        CL(use,0); vi.clear();
        for (i = 1; i <= m + n; ++i){
            /*
        use记录每一天雇用的人数,必须保证每天的人数>=k并且在第n天时要加进人来拿钥匙。我们只要枚举出1到m + n时的一个循环就好,以后就是每m + n + x个一个循环,这里应该有+x的
            */

            while (use[i] < k || *(vi.rbegin()) + n - 1 == i){
                vi.push_back(i);
                for (j = i; j <= i + n - 1; ++j) use[j]++;
            }
        }
        printf("%d\n",vi.size());
        vector<int>::iterator it;

        for (it = vi.begin(); it != vi.end(); ++it){
            if (it == vi.end() - 1)
            printf("%d\n",*it);
            else
            printf("%d ",*it);
        }
   }
   return 0;
}

 

 

 

转载于:https://www.cnblogs.com/E-star/archive/2012/10/25/2739977.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值