Allowance
Time Limit: 1000MS | Memory Limit: 65536K |
Total Submissions: 1696 | Accepted: 708 |
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.
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
= = 贪心思路比较明显 但是不是很好写 先从大到小尝试拼凑一次工资量 然后不够的用一个小的补齐
最后确定发工资量 然后更新剩余的硬币 在尝试后仍不能拼凑一次工资量 就退出循环
- - 贪心模拟感觉不好很好写 还是代码能力不够 想的不够多
AC代码如下:
//
// POJ 3040 Allowance
//
// Created by TaoSama on 2015-02-22
// Copyright (c) 2015 TaoSama. All rights reserved.
//
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>
#define CLR(x,y) memset(x, y, sizeof(x))
using namespace std;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;
struct Coin {
int v, c;
bool operator<(const Coin& rhs) const {
return v > rhs.v;
}
} a[25];
int n, p, need[25];
int main() {
#ifdef LOCAL
freopen("in.txt", "r", stdin);
// freopen("out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);
while(cin >> n >> p) {
for(int i = 1; i <= n; ++i)
cin >> a[i].v >> a[i].c;
sort(a + 1, a + 1 + n);
int ans = 0;
while(true) {
int rest = p; //发一次工资
memset(need, 0, sizeof need);
for(int i = 1; i <= n; ++i) { //从大到小尝试
if(a[i].c > 0) {
int t = min(a[i].c, rest / a[i].v);
rest -= t * a[i].v;
need[i] = t;
}
if(rest == 0) break;
}
if(rest > 0) {
for(int i = n; i > 0; --i) { //用小的补齐 抑或最后大于p的
if(a[i].c > 0 && a[i].v >= rest) {
rest = 0;
++need[i];
break;
}
}
}
if(rest > 0) break; //还剩下的说明不能了
int add = INF;
for(int i = 1; i <= n; ++i) //获取发工资次数
if(need[i])
add = min(add, a[i].c / need[i]);
for(int i = 1; i <= n; ++i) //更新剩余硬币
if(need[i])
a[i].c -= add * need[i];
ans += add;
}
cout << ans << endl;
}
return 0;
}