(贪心)P1016 旅行家的预算

P1016 旅行家的预算

(贪心)P1016 旅行家的预算_第1张图片

应用 

题库训练比赛记录讨论

    • 3.8K通过
    • 10.4K提交
  • 题目提供者CCF_NOI
  • 评测方式云端评测
  • 标签NOIp提高组1999
  • 难度普及+/提高
  • 时空限制1000ms / 128MB

 提交  题解   

  • 提示:收藏到任务计划后,可在首页查看。

最新讨论显示

推荐的相关题目显示

题目描述

一个旅行家想驾驶汽车以最少的费用从一个城市到另一个城市(假设出发时油箱是空的)。给定两个城市之间的距离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

说明

N \le 6N≤6,其余数字\le 500≤500

题解:1>. 当从st(当前位置)起的 d 的范围内,存在比当前的油钱小的,那么,填的油要刚好到达这个位置

           2>. 当从st(当前位置)起的 d 的范围内,不存在比当前的油钱小的,那么,首先找到范围内最小油钱的位置(minn),此时要发挥st位置处油的全部作用,即在给位置将油箱全部填满,将当前位置st变成找到的minn位置。

           主要样例:

          100    50   1   1    2

           30    1.5

           50    2.0

           输出 : 135.00

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define eps (1e-8)
#define MAX 0x3f3f3f3f
#define u_max 1844674407370955161
#define l_max 9223372036854775807
#define i_max 2147483647
#define re register
#define pushup() tree[rt]=tree[rt<<1]+tree[rt<<1|1]
#define nth(k,n) nth_element(a,a+k,a+n);  // 将 第K大的放在k位
#define ko() for(int i=2;i<=n;i++) s=(s+k)%i // 约瑟夫
#define ok() v.erase(unique(v.begin(),v.end()),v.end()) // 排序,离散化
using namespace std;

inline int read(){
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' & c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}

typedef long long ll;
const double pi = atan(1.)*4.;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fLL;
const int M=63;
const int N=5e5+5;
double d1,c,d2,p,x[25],y[25];
int n;

struct fun{
    double x,y;
}f[100];

bool cmp(fun a,fun b){
    return a.x>d1>>c>>d2>>p>>n;
    for(int i=1;i<=n;i++){
        scanf("%lf %lf",&f[i].x,&f[i].y);
    }

    sort(f+1,f+n+1,cmp);
    int leap=0;
    double ans=0,st=0,cut=0,d=c*d2;
    //  ans最终结果  st当前位置  cut油箱当前剩余油量  d范围大小
    while(true){
        double minn=inf;
        int num=0,h=0;
        for(int i=1;i<=n;i++){   //  找范围中油价最小的位置
            if(f[i].x>st&&(f[i].x-st)<=d){
                num++;
                if(minn>=f[i].y){
                    minn=f[i].y;
                    h=i;
                }
            }
        }
        if(!num){         // 没有一个,即不存在加油站了
            if(d<(d1-st)){   // 从当前位置加满油都到达不了终点
                leap=1;
                break;
            }
            else{
                ans+=((d1-st)/d2-cut)*p;  // 可以到达终点,加上
                break;
            }
        }
        if(minn<=p){      //  在该范围内存在比当前位置小的油价
            ans+=((f[h].x-st)/d2-cut)*p;
            p=minn;
            st=f[h].x;
            cut=0;
        }
        else{    //  在该范围内不存在比当前位置小的油价
            if(d>=(d1-st)){   // 如果从当前位置可以直接到达终点
                ans+=((d1-st)/d2-cut)*p;
                p=minn;
                st=d1;
                break;
            }
            else{     //  到达不了
                ans+=(c-cut)*p;
                cut=c-(f[h].x-st)/d2;
               // printf("ans === %lf\n",ans);
                p=minn;
                st=f[h].x;
            }
        }
    }
    if(leap)
        printf("No Solution\n");
    else
        printf("%.2lf\n",ans);
    return 0;
}

 

你可能感兴趣的:(贪心)