您的位置:首页 > 其它

九度oj 1437 To Fill or Not to Fill

2017-09-01 21:20 260 查看

九度oj 1437 To Fill or Not to Fill

题目描述:

With highways available, driving a car from Hangzhou to any other city is easy. But since the tank capacity of a car is limited, we have to find gas stations on the way from time to time. Different gas station may give different price. You are asked to carefully design the cheapest route to go.

输入:

For each case, the first line contains 4 positive numbers: Cmax (<= 100), the maximum capacity of the tank; D (<=30000), the distance between Hangzhou and the destination city; Davg (<=20), the average distance per unit gas that the car can run; and N (<= 500), the total number of gas stations. Then N lines follow, each contains a pair of non-negative numbers: Pi, the unit gas price, and Di (<=D), the distance between this station and Hangzhou, for i=1,…N. All the numbers in a line are separated by a space.

输出:

For each test case, print the cheapest price in a line, accurate up to 2 decimal places. It is assumed that the tank is empty at the beginning. If it is impossible to reach the destination, print “The maximum travel distance = X” where X is the maximum possible distance the car can run, accurate up to 2 decimal places.

样例输入:

50 1300 12 8

6.00 1250

7.00 600

7.00 150

7.10 0

7.20 200

7.50 400

7.30 1000

6.85 300

50 1300 12 2

7.10 0

7.00 600

样例输出:

749.17

The maximum travel distance = 1200.00

题目大意

随着高速公路的使用,开车从杭州到其他城市变得很容易。但是由于一辆车的油箱容量是有限的,在路上我们必须时不时的找加油站。不同的加油站有不同的价格,因此你需要设计一个最便宜的路径。

其中Cmax表示油箱的最大容量,D表示杭州到临近城市的距离,Davg表示每单位的油可行驶的距离,N表示加油站的数目。

分析

这是一道贪心算法(用局部最优去得到整体最有)的题目。要解决这个问题首先要明白两个问题,其一,在哪个加油站加油,其二加多少油。首先对距离进行排序,然后很自然的有如下感受:

(先假设可以到下一个点)

一、如果油箱里有足够油,那么在所能到达的那些加油站中选择一个最便宜的加油

二、移动到下一个比当前位置便宜的加油站

三、如果没有比当前位置便宜的加油站,那么就在当前位置加满油

代码

#include<stdio.h>
#include<algorithm>
using namespace std;

struct station{
double price;
double position;
bool operator < (const station &A) const{
return position < A.position;
}
}buf[502];

int main() {
double cmax;        // 最多装多少汽油
double d;           // 需要行驶的距离
int davg;       //  每kg汽油行驶的距离
int n;          // 加油站的数目
double len;         // 一箱油可以跑多远
double curCapacity; // 当前油箱里的油
double curPrice;    // 当前油价
int index;          // 当前的是在哪个加油站
double minPrice;
double sum;         // 一共花了多少钱
int flag;
while((scanf("%lf%lf%d%d", &cmax, &d, &davg,&n)) !=EOF) {
for (int i = 0; i < n; i++) {
scanf("%lf%lf",&buf[i].price, &buf[i].position);
}
// 初始化最后一个加油点,单价设置为0
buf
.price = 0;
buf
.position = d;
sort(buf, buf+n + 1);
len = davg * cmax;

if (buf[0].position != 0) {
printf("The maximum travel distance = 0.00\n");
continue;
} else {
flag = 1;
curCapacity = 0;
sum = 0;
for (int i = 0; i < n;) {
if((buf[i+1].position - buf[i].position) > len) {
flag = 0;
printf("The maximum travel distance = %.2lf\n", buf[i].position + len);
break;
} else {
index = i;
minPrice = buf[index].price;
for (int j = i; j < n + 1; j ++) {
// 当前油所能到达的站中,价格最便宜的
if (buf[j].position <= buf[i].position + curCapacity * davg && minPrice > buf[j].price) {
minPrice = buf[j].price;
index = j;
}
}
if (index != i) {
curCapacity -= (buf[index].position - buf[i].position)/davg;
i = index;
continue;
}

// 所能到达的最大位置,如果期间有比当前位置价格便宜的,就只加移动到该位置需要的油
// 找到最近的一个比当前便宜的站点
index = i;
minPrice = buf[index].price;
for (int j = i ; j < n + 1; j++) {
if (buf[j].position <= buf[i].position + len && minPrice > buf[j].price) {
// minPrice = buf[j].price;
index = j;
break;
}
}
if (index != i) {
sum += ((buf[index].position - buf[i].position)/ davg -curCapacity)* buf[i].price;
curCapacity = 0;
i = index;
continue;
}

// 所能到达的最大位置,如果期间没有比当前位置价格便宜的,就在当前位置加满油
index = i;
minPrice = 1e18;
for (int j = i + 1; j < n + 1 ; j ++) {
if (buf[j].position <= buf[i].position + len && buf[j].price < minPrice) {
minPrice = buf[j].price;
index = j;
}
}
sum += (cmax-curCapacity)*buf[i].price;
curCapacity = cmax - (buf[index].position - buf[i].position)/davg;
i = index;
}
}
}
if (flag)
printf("%.2lf\n", sum);

}
return 0;
}

/**************************************************************
Problem: 1437
User: gongdazzz
Language: C++
Result: Accepted
Time:10 ms
Memory:1028 kb
****************************************************************/


总结与思考

贪心的思想就是通过局部的最优解来获得整体最优,这道贪心题目有点复杂,前面分析的时候也只是给出了直觉上的贪心,没有严格证明贪心策略是否正确。

虽然知道题目的大体思路,但是就是写不出来,然后参考了http://www.xuebuyuan.com/2079410.html这篇文章。

写出来之后跑给的两个例子是正确的,但是在oj上面总是报错,看了好几遍,整体思路没问题啊!然后发现第一个if的判断里面没有continue!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  贪心算法 九度oj