/*
translation:
有价值为分别为Ai的货币各Bi个,现在要求对其分堆,每堆的价值不得少于c,求最多分多少堆?
solution:
贪心
首先将价值大于c的货币全部都分完,然后对价值小于c的进行贪心。首先按其价值从大到小排序,
再从大到小凑成最接近c但不超过c的堆,然后从小到大遍历,找到一个加上去恰好大于等于c的货币
这样就分完了一堆。
note:
date:
2016.10.23
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 30;
int n, c;
struct Coin
{
int val, num;
Coin(int v=0, int n=0):val(v),num(n){}
bool operator < (const Coin& rhs) const
{
return val > rhs.val; //从大到小排序
}
};
vector<Coin> v;
int main()
{
//freopen("in.txt", "r", stdin);
while(~scanf("%d%d", &n, &c))
{
v.clear();
int val, num, ans = 0;
for(int i = 0; i < n; i++)
{
scanf("%d%d", &val, &num);
if(val < c) v.push_back(Coin(val, num));
else ans += num;
}
//按照val值,从大到小排列
sort(v.begin(), v.end());
for(;;)
{
int res = c, len = v.size();
for(int i = 0; i < len; i++) //从大到小选择组合成一个最接近c但是不超过c
{
if(v[i].num)
{
int t = min(v[i].num, res / v[i].val);
res -= t * v[i].val;
v[i].num -= t;
}
if(!res) break;
}
//从小到大选择一个刚好超过c的最小值
if(res > 0)
{
for(int i = len-1; res > 0 && i >= 0; i--)
{
if(v[i].num && res <= v[i].val)
{
res -= v[i].val;
v[i].num--;
break;
}
}
}
if(res > 0) break;
ans++;
}
printf("%d\n", ans);
}
return 0;
}
poj3040(一般贪心,容器类)
最新推荐文章于 2023-07-09 16:03:37 发布