【問題点】
ガソリンを入れてからnキロ走れる。旅の途中にいくつかのガソリンスタンドがあり、途中で給油する回数が減ります。アルゴリズムは、最良の給油計画を出力するように設計されています。
たとえば、ルートに沿って9つのガソリンスタンドがあり、合計距離が100キロメートルで、ガソリンを充填した後の車の最大距離が20キロメートルであるとします。給油する車の位置を写真に示します。
【分析】
途中で給油する頻度を減らすために、一度給油してから次回給油した後、できるだけ遠くまで走行する必要があります。この設計アイデアに従って、次の貪欲な選択戦略を策定します。
(1)初めて車が始点から出発し、n = 20 kmまで走行するときは、終点に最も近いガソリンスタンドxiを選択し、始点から20km離れたガソリンスタンドを選択します。給油する2番目のガソリンスタンド。
(2)給油後、車は満燃料状態になり、発進前の状態と一致します。こうすることで、問題は、給油回数が最小となる小さなサブ問題になります。 xiから最後まで車。
上記の戦略に従ってサブ問題の解決を続けます。つまり、最後に選択したガソリンスタンドからn km以内にある最寄りのガソリンスタンドを見つけて、毎回給油します。
特定のプログラム設計では、配列xは、ガソリンスタンドと開始点の間の距離を格納するように設定されます。旅全体の長さはSで表され、選択されたガソリンスタンドは配列aで保存され、合計は通過した最長の旅を表します。
コード:
#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");
}
結果: