zoukankan      html  css  js  c++  java
  • 机智零崎不会没梗Ⅰ (贪心算法)

    题目描述

    之前的上机中,背包问题已经基本都和大家混了个脸熟,不过还有一种不是背包却以背包为名的问题,零崎只能说“我从未见过如此厚颜无耻之包”。梗玩过了,就进入正题。

    M87星云盛产矿物,有红色的绿色的黄色的蓝色的银色的白色的……不同颜色的矿物产量不同用途不同自然价值也不一样。隔壁M78星云的人虽然说主要是用银色的做头盔,不过其他颜色的还可以拿来卖给地球人啊23333

    某外星生物一次可以携带重量为G的矿物,现在他们面前有K块重量W,价值V的矿石,不过他们很厉害所以可以把矿石搓成矿砂再把矿砂搓成矿石。

    外星生物穿越星际路费可是很贵的,如果他们带来的矿石价值不足N,则请你补足路费,否则你只要大喊一声summon,他们就会出现了!

    输入

    多组输入数据

    第一行为三个整数,分别为描述中的G K N

    接下来K行,每行两个整数为W,V。

    K小于10000,其他数据保证在int范围内,且W不为0

    输出

    对于每组数据,输出一行,为“summon!”或者需要补充的路费,结果保留3位小数。

    输入样例

    3 2 1
    1 2
    2 3
    1 1 10
    1 5

    输出样例

    summon!
    5.000
    题目来源:http://biancheng.love/contest/23/problem/B/index
    解题思路:贪心算法。
    根据题目可知,既然外星人可以把矿石搓成矿砂再把矿砂搓成矿石,那么我们所要做的就是:求出外星人在最大载重为G时,携带矿石价值的最大值。如果该最大值比N小,需要输入路费也就是差了多少钱,如果大于N,输出summon! 那么本体的关键在于求出最大价值。
    下面分析最大值如何求解:
    1、将矿石的性价比进行排序(所谓性价比也就是单位质量矿石的价格),外星人每次将矿砂搓成矿石的顺序按照矿石的性价比依次进行。
    2、将矿砂逐个搓成矿石,放入外星人的口袋中,同时这种矿石的数量减一。(意思就是外星人只能还原矿石不能把原来性价比为1的矿石搓成性价比为100的矿石)。
    3、在外星人将矿石放到自己的口袋的时候,需要帮助他判断是否能够装得下。同时我们还要记下一笔帐:这个外星人现在装的矿石价值总共是多少。
    4、输出的判断。判断最大值和N之间的关系。输出格式printf("%.3lf ",N-ans); 或者输出printf("summon! ");
    通过上述的讲解,我们在对矿石的性价比排序的时候可以采用结构体的形式。包括矿石的价值,数量,性价比。
    给出本题的代码:
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 struct node{
     4     double w;
     5     double v;
     6     double temp;
     7 };
     8 
     9 bool cmp(node a,node b)
    10 {
    11     return a.temp>b.temp;
    12 };
    13 
    14 int main()
    15 {
    16     int K;
    17     double G,N,ans;
    18     while(~scanf("%lf%d%lf",&G,&K,&N))
    19     {
    20         ans=0;
    21         node no[K];
    22         for(int i=0;i<K;i++)
    23         {
    24             scanf("%lf%lf",&no[i].w,&no[i].v);
    25             no[i].temp=no[i].v/no[i].w;
    26         }
    27         sort(no,no+K,cmp);
    28         for(int i=0;i<K;i++)
    29         {
    30             if(G>=no[i].w)
    31             {
    32                 ans+=no[i].v;
    33                 G-=no[i].w;
    34             }
    35             else
    36             {
    37                 ans=ans+G*(no[i].temp);
    38                 G=0;
    39             }
    40         }
    41         if(ans>=N)
    42             printf("summon!
    ");
    43         else
    44             printf("%.3lf
    ",N-ans);
    45     }
    46 }
    
    
  • 相关阅读:
    抽象类与抽象方法
    简单工厂模式
    面向对象的七种基本设计原则
    HashTable集合遍历的三种方法
    继承(父类为虚方法以及子类的重写)
    继承(is与as)
    Chrome OS 更新新版本可让Linux访问USB连接的Android设备
    谷歌对Intel 10nm进度不满
    盖茨对没能做好手机系统对抗苹果表示遗憾
    微软内部封杀 Slack
  • 原文地址:https://www.cnblogs.com/zpfbuaa/p/5002039.html
Copyright © 2011-2022 走看看