贪心篇

贪心基本思路:

A.排序  当n=2时,算出结果,两数交换,比较怎么排列更优(国王的游戏)

B.如果不能排序,模拟最优选择的过程(旅行家的预算)

例1:奶牛晒衣服

题目背景

熊大妈决定给每个牛宝宝都穿上可爱的婴儿装 。但是由于衣服很湿,为牛宝宝晒衣服就成了很不爽的事情。于是,熊大妈请你(奶牛)帮助她完成这个重任。

题目描述

一件衣服在自然条件下用一秒的时间可以晒干 aa 点湿度。抠门的熊大妈只买了一台烘衣机 。使用用一秒烘衣机可以让一件衣服额外烘干 bb 点湿度(一秒晒干 a+ba+b 湿度),但在同一时间内只能烘一件衣服。现在有 nn 件衣服,第 ii 衣服的湿度为 w_iwi(保证互不相同),要你求出弄干所有衣服的最少时间(湿度为 00 为干 )。

输入格式

第一行三个整数,分别为 n,a,bn,a,b。
接下来 22 到 n+1n+1 行,第 ii 行输入 w_iwi

输出格式

一行,弄干所有衣服的最少时间。

输入输出样例

输入 #1
3 2 1
1
2
3
输出 #1 

贪心思路:

每天从剩下没干的衣服里选择一个最湿的,并排好序

#include<bits/stdc++.h>
using namespace std;
int w[1000];
int j;
bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
    int n,a,b;
    cin>>n>>a>>b;
    for(int i=1;i<=n;i++)
      cin>>w[i];
    sort(w+1,w+n+1,cmp);
    int time=0;   
    int p;
    while(1)
    {
        if(w[1]<=time*a) break; //如果这件衣服在自然条件下能干 就不用烘干了(因为之前在烘干其他衣服时候已经晾干过一会了)
        w[1]-=b;  //烘干一天
        p=w[1];   
        for(j=2;w[j]>p&&j<=n;j++)  //因为都已经排好序了,所以如果
        {
            w[j-1]=w[j];     //所有比当前衣服湿的都往前移
        }   
        w[j-1]=p; //把这件衣服放到合适的位置
        time++;  //过了一天
    }
    cout<<time;
    return 0;
}

 

例二:旅行家的预算

题目描述

一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离D1D1、汽车油箱的容量CC(以升为单位)、每升汽油能行驶的距离D2D2、出发点每升汽油价格PP和沿途油站数NN(NN可以为零),油站ii离出发点的距离DiDi、每升汽油价格PiPi(i=1,2,…,Ni=1,2,,N)。计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。

输入格式

第一行,D1D1,CC,D2D2,PP,NN。

接下来有NN行。

i+1i+1行,两个数字,油站i离出发点的距离DiDi和每升汽油价格PiPi。

输出格式

所需最小费用,计算结果四舍五入至小数点后两位。如果无法到达目的地,则输出“No Solution”。

输入输出样例

输入 #1
275.6 11.9 27.4 2.8 2
102.0 2.9
220.0 2.2
输出 #1
26.95


贪心思路:
先查找在自己最大能到达的范围中最小的加油站,然后在现在的加油站正好加够能到那个最便宜的加油站的油,
·如果有其他更便宜的加油站,在现在的加油站正好加够能到那个最便宜的加油站的油

·如果没有比目前的加油站更便宜的,那就从目前的加油站加满油,然后在从后面的加油站里选一个最便宜的
·如果没有比目前加油站更便宜的,但可以到达终点,就直接在目前的加油站里加够到终点的油直接结束
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 double d[1000],pi[1000];
 4 int main()
 5 {
 6     double d1,c,d2,p,pz=0,pmin=10000,l=0;//l表示现在油箱里面还有多少油,pz表示钱数, 
 7     int n;
 8     cin>>d1>>c>>d2>>p>>n;
 9     pi[0]=p;
10     d[0]=0;
11     double x=c*d2; //x表示当油箱满的时候最多能走多少路
12     for(int i=1;i<=n;i++)
13      {
14          cin>>d[i]>>pi[i];
15      }
16     for(int i=1;i<=n;i++)
17     {
18         if(d[i]-d[i-1]>x)  //如果任意相邻的加油站之间的距离大于最多能走的路 就是无解 
19         {
20             cout<<"No Solution";
21             return 0;
22         }
23     }
24     double d0=0;   //表示已经走了多少路 
25     int ii=0;
26     while(d1-d0>0)  //如果d1-d0=0 说明旅行家已经到了终点,直接退出 
27     {
28         for(int i=ii+1;d[i]-d0<=x&&i<=n;i++)  // 在范围之内
29         {
30             if(pi[i]<pmin) 
31             {
32                 pmin=pi[i];
33                 ii=i;
34             }
35         }
36         if(pmin<=p)  //范围内的加油站比自己还便宜,那就使加的油刚好能支持到达这个加油站 
37         {
38             pz+=((d[ii]-d0)/d2-l)*p;//(d[ii]-d0)/d2表示到收费最少的加油站需要的油一共多少升, 
39             l=(d[ii]-d0)/d2;  //灌满 
40         }
41         else if(d1-d0>x)//这种情况指的是范围内的加油站都比自己贵,并且无法一次到达终点,所以应该在自己这个最便宜的加油站直接加满
42         {
43          pz+=(c-l)*p;
44          l=c;
45         }
46         else  //这种情况 指的是范围内的加油站都比自己贵,但能一次到达终点,那我肯定不管后面加油站了,直接奔向终点
47         {
48             pz+=((d1-d0)/d2-l)*p;
49             break;    //到了终点停止 
50         } 
51         l=l-(d[ii]-d0)/d2;//走多少里程,就相应地减去多少油 
52         d0=d[ii];//更新d0,表示旅行家的移动 
53         p=pmin;//更新p,方便下次进行比较 
54         pmin=10000;//还原pmin,以便下次搜索最小值 
55     }
56     printf("%.2lf",pz);
57     return 0;
58 }

 









posted @ 2021-03-27 11:16  -Sky-  阅读(84)  评论(0编辑  收藏  举报