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.
#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; }