Openjudge-4110-圣诞老人的礼物

这一题是一道贪心的题目,但是它比较特殊的地方在于糖果可以分开拿,我们不必整箱拿,所以我们可以直接就把糖果按照价值比从大到小排序,然后整箱装不下的时候,剩余重量乘以它的价值比,这样就算出来了。

对于结构体的排序,这里的重载就是运算符的重载,这个结构体很像类。我们不必接受两个参数,直接只接收后一个,然后进行比较即可。

这个贪心直观看上去是正确的,下面我们来证明一下:

我们假设你觉得的一个价值最大的糖果拿法,它的序列是 A ,我们按照价值比拿的糖果序列为 B ,我们将 A 序列按照价值比降序排列。

我们比较 A i  和  B i ,如果它们相等,我们就向后比较,直到第一个不相等的,那一定是 Bi 大于 Ai,因为 Bi 是按价值比从大到小排列的,除非你也是这样选的,否则你选的肯定要小于 Bi 。

那这样的话,Ai就可以用Bi替换,我们此时就可以选择Bi,不再选择Ai,但是这时候 A 序列的价值就增加了,这和它是最大价值序列矛盾,所以按照价值比降序排列的取法就是正确的。

#include <iostream>
#include <algorithm>
using namespace std;
const double eps=1e-6;
 
struct Candy {
    int v,w;
    bool operator < (const Candy &c)
    {
        return double(v)/w-double(c.v)/c.w>eps;
    }
}candy[110];
 
int main()
{
    int N,W;
    cin>>N>>W;
    for (int i=0;i<N;i++) {
        cin>>candy[i].v>>candy[i].w;
    }
    double totalV=0;
	int totalW=0;
    sort(candy,candy+N);
    for (int i=0;i<N;i++) {
        if (totalW+candy[i].w<W) {
            totalW+=candy[i].w;
            totalV+=candy[i].v;
        }
        else {
            totalV+=double(candy[i].v)/candy[i].w*(W-totalW);
            break;
        }
    }
    printf("%.1lf\n",totalV);
    return 0;
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值