P1016 旅行家的预算
应用
-
- 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<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<bitset>
#include<iomanip>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#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<b.x;
}
int main(){
cin>>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;
}