奶牛晒衣服(题解)
奶牛晒衣服
【问题描述】
在熊大妈英明的带领下,时针和他的同伴生下了许多牛宝宝。熊大妈决定给每个宝宝都
穿上可爱的婴儿装。于是,为牛宝宝洗晒衣服就成了很不爽的事情。
圣人王担负起了这个重任。洗完衣服后,你就要弄干衣服。衣服在自然条件下用1 的时
间可以晒干A 点湿度。抠门的熊大妈买了1 台烘衣机。使用烘衣机可以让你用1 的时间使1
件衣服除开自然晒干的A 点湿度外,还可烘干B 点湿度,但在1 的时间内只能对1 件衣服使
用。
N 件的衣服因为种种原因而不一样湿,现在告诉你每件衣服的湿度,要你求出弄干所有
衣服的最少时间(湿度为0 为干)。
【输入格式】
第一行N , A , B , 接下来N 行, 每行一个数, 表示衣服的湿度( 1<= 湿
度,A,B<=500000,1<=N<=500000)。
【输出格式】
一行,最少时间。
【输入样例】Dry.in
3 2 1
1
2
3
【输出样例】Dry.out
1
【样例解析】
第1 个时间内,用机器处理第3 件衣服,此外,所有衣服自然晒干2。花费1 时间全部
弄干。
这道题用贪心即可解答:排序,取每次最大的湿度的衣服来烘干,自然风干后再次排序,以此类推,直到最大湿度的衣服湿度值为<0的为止。
当然,这个的复杂度我也只能呵呵了,于是想到了每次不用把所有衣服的湿度值都减去,只要记录总共减去的湿度值和最大湿度的衣服进行比较即可,当减去湿度值大于等于最大湿度就可以输出。虽然减少了一次循环,但两次排序的2 * nlogn 的复杂度也不能过完50W的数据。
因此,我们就想到了一个排序复杂度很低的数据结构——优先队列,它会把放入的元素默认从小到大排序,单次插入删除的复杂度仅为logn,所以时间就不怕超了。
下面附上各个AC、没AC的代码:
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <cmath> #include <cstdlib> using namespace std; #define zxy(i , a , b) for(ll i = a ; i <= b ; i ++) #define zxyzxy(i , a , b) for(ll i = a ; i < b ; i ++) #define yxz(i , a , b) for(ll i = a ; i >= b ; i --) #define yxzyxz(i , a , b) for(ll i = a ; i > b ; i --) #define N 500010 typedef long long ll; ll read() { ll ans = 0; char ch = getchar(),last = ' '; while(ch < '0' || ch > '9') last = ch , ch = getchar(); while(ch >= '0' && ch <= '9') ans = ans * 10 + ch - '0' , ch = getchar(); if(last == '-') ans = -ans; return ans; } void put(ll x) { if(x < 0) { putchar('-'); x = -x; } if(x == 0) { putchar('0'); return; } ll q[100] , nn = 0; while(x) q[++ nn] = x % 10 , x /= 10; while(nn) putchar('0' + q[nn]), --nn; } ll n,a,b,t; ll sd[N]; ll ans = 0; ll op = 0; int main() { //freopen("dry.in","r",stdin); //freopen("dry.out","w",stdout); n = read(); a = read(); b = read(); zxy(i , 1 , n) { sd[i] = read(); /*put(sd[i]); printf("\n");*/ } sort(sd + 1 , sd + n + 1); while(1) { sd[n] -= b; op += a; sort(sd + 1 , sd + n + 1); ans ++; if(sd[n] <= op) break; else continue; } put(ans); return 0; }
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <cmath> #include <cstdlib> #include <queue> using namespace std; #define zxy(i , a , b) for(ll i = a ; i <= b ; i ++) #define zxyzxy(i , a , b) for(ll i = a ; i < b ; i ++) #define yxz(i , a , b) for(ll i = a ; i >= b ; i --) #define yxzyxz(i , a , b) for(ll i = a ; i > b ; i --) #define N 500010 typedef long long ll; ll read() { ll ans = 0; char ch = getchar(),last = ' '; while(ch < '0' || ch > '9') last = ch , ch = getchar(); while(ch >= '0' && ch <= '9') ans = ans * 10 + ch - '0' , ch = getchar(); if(last == '-') ans = -ans; return ans; } void put(ll x) { if(x < 0) { putchar('-'); x = -x; } if(x == 0) { putchar('0'); return; } ll q[100] , nn = 0; while(x) q[++ nn] = x % 10 , x /= 10; while(nn) putchar('0' + q[nn]), --nn; } ll n,a,b,wet[N],dry,ti = 0; priority_queue <ll> q; int main() { //freopen("dry.in","r",stdin); //freopen("dry.out","w",stdout); n = read(); a = read(); b = read(); zxy(i , 1 , n) { wet[i] = read(); q.push(wet[i]); } // while(!q.empty()) printf("#%d ",q.top()),q.pop();enter; while(1) { int maxn = q.top(); // printf("#%d\n",maxn); q.pop(); if(maxn <= dry) break; maxn -= b; q.push(maxn); dry += a; ti++; } put(ti); return 0; } /* 3 2 2 6 1 5 */