zoukankan      html  css  js  c++  java
  • 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
    ",totalV);
        return 0;
    }
  • 相关阅读:
    [转帖]译文:如何使用SocketAsyncEventArgs类(How to use the SocketAsyncEventArgs class)
    如何建立一个“绑定友好的”usercontrol--wpf
    安卓学习(三)
    安卓学习(二)
    Android学习1
    用伪代码梳理springboot
    用伪代码梳理javaweb从零开始
    用伪代码梳理spring源码
    java如何写出简洁代码
    JAVA修复微信官方SDK支付XXE漏洞
  • 原文地址:https://www.cnblogs.com/xyqxyq/p/10211342.html
Copyright © 2011-2022 走看看