All Posts ←
← All Posts
poj 3040 Allowance
Tecker Yu
AI Native Cloud Engineer × Part-time Investor
Knowledge Points:
Greedy Algorithm
Solution Report
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string.h>
#include <limits>
using namespace std;
struct Coin {
int d;
int b;
};
bool cmp(const Coin &a, const Coin &b) {
return a.d > b.d;
}
vector<Coin> v;
int N, C;
int need_count[20];
int main() {
scanf("%d %d", &N, &C);
int res = 0;
for(int i=0;i<N;i++) {
struct Coin c;
scanf("%d %d", &c.d, &c.b);
if (c.d >= C) {
res += c.b;
continue;
}
v.push_back(c);
}
sort(v.begin(), v.end(), cmp);
N = v.size();
int i, j;
while(1) {
int sum = C;
memset(need_count, 0, sizeof(need_count));
// Greedily take from largest to smallest until exactly sum or close to sum
for(i=0;i<N;++i) {
if (sum > 0 && v[i].b > 0) {
int has = min(v[i].b, sum / v[i].d);
if (has > 0) {
sum -= has * v[i].d;
need_count[i] = has;
}
}
}
// Greedily take from smallest to largest to reach sum
for(i=N-1;i>=0;--i) {
if (sum > 0 && v[i].b > 0) {
// Allow exceeding one denomination value to make up sum
int has = min(v[i].b - need_count[i], (sum+v[i].d-1) / v[i].d);
if (has > 0) {
need_count[i] += has;
sum -= has * v[i].d;
}
}
}
if (sum > 0) break;
int weeks = numeric_limits<int>::max();
for(i=0;i<N;++i) {
if (need_count[i] == 0) continue;
// Number of times the optimal solution for C can be satisfied, which is weeks
weeks = min(weeks, v[i].b / need_count[i]);
}
res += weeks;
// Finally update remaining coin counts
for(i=0;i<N;++i) {
if (need_count[i] == 0) continue;
v[i].b -= weeks * need_count[i];
}
}
printf("%d\n", res);
return 0;
}Conclusion
Classic greedy algorithm problem, focus on learning greedy thinking patterns.
Views