问题内容
已知一辆汽车加满油后可行驶d(如d=7)km,而旅途中有若干个加油站。编写一个实验程序指出应在哪些加油站停靠加油,使加油次数最少。用a数组存放各加油站之间的距离,例如a[]={2,7,3,6},表示共有n=4个加油站(加油站编号是0 – n-1),从起点到0号加油站的距离为2km,以此类推。
输入:一个n=8的数组。
输出:一个最优的加油方案。
贪心法思想
贪心法的基本思路是在对问题求解时总是做出在当前看来是最好的选择,也就是说贪心法不从整体最优上加以考虑,所做出的仅是在某种意义上的局部最优解。每一次贪心选择都将所求问题简化为规模更小的子问题,并期望通过每次所做的局部最优选择产生出一个全局最优解。
问题分析
汽车加油问题采用贪心法,将尽量减少加油次数,细分为子问题:若汽车能到达下一加油站,则在该加油站不加油。若剩下的汽油不足以到达下一加油站,则加油,累加计算总加油次数。
代码
#include <stdio.h>
int main()
{
int n=8,i=0,num=0; //加油站数量,总计所需加油站
int d=7,road=7;//油量,路途
int a[100]; //加油站距离
printf("请输入各加油站之间的距离(共八个距离):");
for(i=0;i<n;i++){
scanf("%d",&a[i]);
if(a[i]>d){
printf("无法到达!\n");
return 0;
}
}
for(i=0;i<n;i++){
if(road>=a[i])
{
road=road-a[i];//能到达下一加油站后,所剩油量
}
else
{
road=d;//不能到达下一加油站,该站加油
printf("在第%d个加油站加油\n",i);
road=road-a[i];
num++;
}
}
printf("总加油次数为%d\n",num);
}
结果展示
遇到的问题
该问题难度不大,但我在思考过程中两次进入误区,导致花费总计两个多少小时,主要原因如下:
1.对题目了解不清晰。在看到题目时,我初以为是汽车带有一定量的汽油出发,每次只能在加油站加入一定量的汽油,上限不计,尽量减少加油次数。思考如果这样,能否使用贪心算法。面临的问题是,如果后面某一路途较远(比如较长的公路),前面的最优解所带油量不足以走完该段,则无法完成整段路程,这时需要先考虑整段路程油量问题,无法使用贪心算法,在当下做出的最优解不适合后面加油选择,需改用其他方法。
2.在if-else语句使用时,当时else语句中的road=road-a[i];
省略,发生的问题是假设每段路程恰好用完每次加油量,则结果显示为仅在第1、3、5、7个加油站加油,因为在else语句中,仅完成加油,没有减去下该段路程的长度,需要加入road=road-a[i];
语句,减去路程,才能对每一段路途加油进行计算。