Pythonでn台のバイクが走行できる最大距離を求めるアルゴリズム
問題概要
n台のバイクがあり、それぞれ満タンの状態で100km走行できるものとします。このn台を使って到達できる最大距離を求めるのが本記事の目的です。なお、ここではすべてのバイクが同一仕様であり、1km走行するのに1リットルの燃料を消費すると仮定します。
もしn台すべてが同じ地点から並走した場合、走行できる距離は100kmにとどまってしまいます。そこで目標となるのは、燃料の無駄を最小限に抑えながら最大距離を走ることです。燃料の浪費を減らすということは、言い換えれば実際に動かすバイクの台数を最小化することを意味します。
解決のアプローチ:燃料の中継ぎ戦略
バイクを直列的に運用すれば、より遠くまで進むことができます。具体的には、最後尾のバイクから他のバイクへ燃料を受け渡し、ある時点で最後尾のバイクを切り離します(それ以降は走らせません)。
ここで問題になるのは「どの距離の時点で燃料の受け渡しを行うべきか」という点です。条件は次の2つです。
- 合計走行距離が最大になること
- 残りのバイクの燃料タンクが溢れてしまわないこと
答えはシンプルで、残りn台の状態で fuel/n km を走るごとに1台ずつ切り離していくのが最適です。こうすることで、切り離すバイクの残り燃料を他のバイクの空き容量にちょうど収めることができ、一切の燃料ロスが発生しません。
アルゴリズムの手順
- covered_distance を 0 で初期化する
- n > 0 の間、以下を繰り返す
- covered_distance に fuel / n を加算する
- n を 1 減らす
- ループ終了後、covered_distance を返す
この方法では、走行距離は fuel/1 + fuel/2 + … + fuel/n の総和として表されます。
Pythonでの実装例
以下のコードで実際の動作を確認してみましょう。
def maximum_distance(n, fuel):
covered_distance = 0
while (n > 0):
covered_distance = covered_distance + (fuel / n)
n = n - 1
return covered_distance
n = 3
fuel = 100
print(maximum_distance(n, fuel))
入力
3, 100
出力
183.33333333333334
結果の解説
n = 3、fuel = 100 の場合、計算は次のようになります。
- 3台で走る区間:100 ÷ 3 ≒ 33.33 km
- 2台で走る区間:100 ÷ 2 = 50 km
- 1台で走る区間:100 ÷ 1 = 100 km
合計すると 33.33 + 50 + 100 = 約183.33 km となり、単純に並走した場合の100kmを大きく上回る結果が得られます。時間計算量は O(n)、空間計算量は O(1) と非常に効率的なアルゴリズムです。
-
Pythonで最大の成功確率を持つパスを見つけるプログラムの実装方法
問題の概要 n 個のノード(ノードには 0 から順に番号が振られています)からなる無向重み付きグラフを考えます。このグラフは辺リスト(edge list)として入力され、各辺 e には「その辺を通過する際の成功確率」probability[e] が割り当てられています。さらに、開始ノード(start)と終了ノード(end)も与えられます。 求めたいのは、start から end へ移動するときに成功確率が最大となる経路であり、答えとしてその成功確率を返します。経路がひとつも存在しない場合は 0 を返してください。 たとえば、次のような入力が与えられたとします。 この場合の出力は 0.25
-
Pythonで等間隔に置かれた石をすべて回収する際の総移動距離を求める方法
問題の概要あるレース大会が開催されるとしましょう。道路上には複数の石が一直線に並んで置かれており、スタート地点にはバケツが用意されています。バケツから最初の石までは6単位の距離があり、それ以降の石は互いに4単位ずつ離れて配置されています。参加者はバケツから出発し、最も近い石を拾ってバケツまで戻り、そこに石を入れます。その後、再び走って次の石を取りに行き、また戻ってバケツに入れる——この手順を、すべての石がバケツに収まるまで繰り返します。石がn個あるとき、参加者が移動する必要のある総距離を求めるのがこの問題です。たとえば入力が n = 5 の場合、出力は 140 になります。これは次の計算による