Allowance
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 2921 | Accepted: 1178 |
Description
As a reward for record milk production, Farmer John has decided to start paying Bessie the cow a small weekly allowance. FJ has a set of coins in N (1 <= N <= 20) different denominations, where each denomination of coin evenly divides the next-larger denomination (e.g., 1 cent coins, 5 cent coins, 10 cent coins, and 50 cent coins).Using the given set of coins, he would like to pay Bessie at least some given amount of money C (1 <= C <= 100,000,000) every week.Please help him ompute the maximum number of weeks he can pay Bessie.
Input
* Line 1: Two space-separated integers: N and C
* Lines 2..N+1: Each line corresponds to a denomination of coin and contains two integers: the value V (1 <= V <= 100,000,000) of the denomination, and the number of coins B (1 <= B <= 1,000,000) of this denomation in Farmer John's possession.
* Lines 2..N+1: Each line corresponds to a denomination of coin and contains two integers: the value V (1 <= V <= 100,000,000) of the denomination, and the number of coins B (1 <= B <= 1,000,000) of this denomation in Farmer John's possession.
Output
* Line 1: A single integer that is the number of weeks Farmer John can pay Bessie at least C allowance
Sample Input
3 6 10 1 1 100 5 120
Sample Output
111
老板要给员工发工资,有1,5,10,50面值的美分硬币,每周最少付c美分,问最多能付多少周
先按面值大的来,刚开始想错了,想取一个大,在凑几个小,睡了一觉缓缓脑子想明白了
从大一直取到到小,不能超过c,少了用小的补,才是最优
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct node{
int dem, num;
}co[1010];
bool cmp(node x, node y){
return x.dem < y.dem;
}
int need[1010];
int main(){
int rest, lim, ans, t, m, n, c;
while(scanf("%d%d", &n, &c) == 2){
for(int i = 0; i < n; i++){
scanf("%d%d", &co[i].dem, &co[i].num);
}
ans = 0;
t = 1e8;
sort(co, co+n, cmp);
for(lim = n-1; lim >= 0; lim--){//先把面额超过工资的取完
if(co[lim].dem >= c){
ans += co[lim].num;
continue;
}
break;
}
while(1){
rest = c;
memset(need, 0, sizeof(need));
for(int i = lim; i >= 0; i--){//计算每种方式各种硬币硬币各需要多少个加一块接近c但不超过c
if(!co[i].num || !rest){
continue;
}
t = rest / co[i].dem;
t = min(t, co[i].num);
need[i] = t;
rest -= t * co[i].dem;
}
if(rest){//如果不是正好相等就用小的补
for(int i = 0; i <= lim; i++){
if(rest <= co[i].dem && (co[i].num - need[i])){//上面已经确定最接近c,所以只需一个最小的硬币就够了
need[i]++;
rest = 0;
break;
}
}
if(rest){//如果没有,就说明钱不够了,结束
break;
}
}
m = 1e8;
for(int i = 0; i <= lim; i++){
if(need[i]){
m = min(m, co[i].num / need[i]);
}
}
ans += m;
for(int i = 0; i <= lim; i++){
co[i].num -= m * need[i];
}
}
printf("%d\n", ans);
}
return 0;
}