【问题】
一辆汽车 加满油后可以行使n千米。旅途中有若干个加油站,途加油次数减少,设计一个算法,输出最好的加油方案。
例如,假设沿途有9个加油站,总路程为100千米,加满油后汽车的最远距离为20千米。汽车加油的位置如图所示。
【分析】
为了使汽车在途中加油次数减少,需要让汽车加过一次油 后行使的路程尽可能的远,然后再加下一次油。按照这种设计思想,制定以下贪心选择策略:
(1)第1次汽车从起点出发,行使到n=20千米时,选择一个距离终点最近的加油站xi,应选择距离起点为20千米的加油站即第2个加油站加油。
(2)加完-次油后,汽车处于满油状态,这与汽车出发前的状态一致,这样就将问题归结为求xi到终点汽车加油次数最少的一一个规模更小的子问题。
按照以上策略不断地解决子问题,即每次找到从前一次选择的加油站开始往前n千米之间、距离终点最近的加油站加油。
在具体的程序设计中,设置一-个数组x,存放加油站距离起点的距离。全程长度用S表示,用数组a存放选择的加油站,total 表示已经行使的最长路程。
code:
#include<stdio.h>
#include <iostream>
#define S 100 /*S:全程长度*/
void main()
{
int i, j, n, k = 0, total, dist;
int x[] = { 10,20,35,40,50,65,75,85,100 }; /*数组x:加油站位置(距离起点的位置)*/
int a[10]; /*数组a:选择加油点的位置*/
n = sizeof(x) / sizeof(x[0]); /*n:沿途加油站的个数*/
printf("请输入最远行车距离(15<=n<100):");
scanf("%d", &dist);
total = dist; /*total:总共行使的公里数*/
j = 1; /*j:选择的加油站个数*/
while (total < S) /*如果汽车未走完全程*/
{
for (i = k; i < n; i++)
{
if (x[i] > total) /*如果距离下一个加油站太远*/
{
a[j] = x[i - 1]; /*则在当前加油点加油*/
j++;
total = x[i - 1] + dist; /*计算加完油后能行使的最远距离*/
k = i; /*k:记录下一次加油的开始位置*/
break; /*退出for循环*/
}
}
}
printf("行驶%d公里应该选择的加油点:\n", S);
for (i = 1; i < j; i++) /*输出选择的加油点*/
printf("%4d", a[i]);
printf("\n");
system("pause");
}
结果: