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;

}

 

 

 

你可能感兴趣的:(codeforces)