您的位置:首页 > 其它

POJ 3040 Allowance

2016-02-29 23:55 183 查看
POJ 3040题目大意如下:

(最近做的题总是FJ和他的奶牛。。。)FJ想给他的奶牛奖赏,准备的奖金分成N组,每周发给奶牛的奖金不能少于C,每一组都是同一种面值的硬币,同时还告诉了每一组硬币的数量。现在要去寻找一种最佳方案,使得能够最大周数分发奖金。

还有一点(最近看题总是丢三落四):从最小面值到最大面值,前一面值能够整除后一大的面值。

关于题目给出的这个整除关系,开始没有看到,折磨了半天,后来看到了,却还是不是很懂,所以接下来的东西都是参考别人的代码。当然还是贪心:

1)原则上是尽量满足选中的面值总额可以接近C,只能大于等于,而且不多太多;

2)由1)中可知,挑选的原则是先找大面额的,尽量使得面额总值接近C,接下来用小面额(尽量小,也就是从小到大刷选)的去补充;

以上挑选原则可以保证每次挑选都是最优的方案,原因在于:大面额是小面额的倍数,存在可以用足够量的小面额来代替大面额的情况,那么这样一来就浪费了小面额,所以一开始尽量使用大面额,之后再用小面额补充

代码如下:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <limits>

using namespace std;
const int maxn = 20;

struct Node {
int value, B;
}deno[maxn];
int N, C;
int per[maxn];

bool camp(const Node& lhs, const Node& rhs) {
return lhs.value > rhs.value;
}

void solve() {
int weeks = 0;
//从大到小排序:按照Value的大小
sort(deno, deno + N, camp);
//先将value大于C的组直接拿出来
for (int i = 0; i < N; i++) {
if (deno[i].value >= C) {
weeks += deno[i].B;
deno[i].B = 0;
}
else break;
}
//循环处理每一组搭配
while (true) {
int sum = C;
memset(per, 0, sizeof(per));
//先从大到小挑选,但是挑选时要注意不能使得总的和大于C
for (int i = 0; i < N; i++) {
if (deno[i].B == 0) continue;
int temp = min(deno[i].B, sum / deno[i].value);
if (sum > temp*deno[i].value) {
sum -= temp*deno[i].value;
per[i] = temp;
}
}
//接下来从小到大挑选,挑选的时候总和可以稍微大于C
for (int i = N - 1; i >= 0; i--) {
if (deno[i].B <= 0) continue;
if (sum < 0) break;
int temp = min(deno[i].B - per[i], (sum + deno[i].value - 1) / deno[i].value);
sum -= temp*deno[i].value;
per[i] += temp;
}
//如果没有这种情况,那么说明所有情况已经挑选完毕
if (sum > 0) break;

int ave = numeric_limits<int>::max();
for (int i = 0; i < N; i++) {
if (per[i] != 0) ave = min(ave, deno[i].B / per[i]);
}
weeks += ave;
//如果这组搭配存在,那么更新每一组硬币的数量
for (int i = 0; i < N; i++) if (deno[i].B != 0) deno[i].B -= ave*per[i];
}
printf("%d\n", weeks);
}

int main(int argc, const char * argv[]) {
// insert code here...
while (scanf("%d %d", &N, &C) != EOF) {
for (int i = 0; i < N; i++) scanf("%d %d", &deno[i].value, &deno[i].B);
solve();
}
return 0;
}

Accept 648K /0MS
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM ICPC poj 穷竭 贪心