問題定義
n
同じ容量のバケットがm
隣り合っています。1 つのバケツから右のバケツに水を注ぐことができます。目標は、すべてのバケツを別の容器に空にすることですが、空にできるのは右端のバケツだけです。それらはそれぞれ、特定の初期量の水を持っています。w
ここで0 <= w <= m
、 とw
は整数です。6 6 -> 3 9 で 3 だけを注ぐ場合、それは許可されません。注ぐ場合は、できるだけ注ぐ必要があるため、合法的な動きは 6 6 -> 2 10 になります。
すべてのバケツを空にするために必要な移動の最小数は? バケットの最大数は 1000 で、最大容量は 100 です。
例
例 1
4 つのバケツ容量 10 以下の量の水: 4 0 6
答えは 4 0 6 -> 0 4 6 -> 0 0 10 -> 0 0 0 で、3 手です。
例 2
3 バケット容量 10、8 9 3
8 9 3 -> 8 2 10 -> 0 10 10 -> 0 10 0 -> 0 0 10 -> 0 0 0 = 合計 5 回の移動
最初にさまざまな種類のアルゴリズム (貪欲、動的、バックトラッキングなど) で試してみましたが、どれもうまくいかないようでした。私はかなり直感的な解決策を見つけたと思っていましたが、これらの答えをチェックするプログラムはそれが間違っていると私に言ったので、間違っているかもしれません. もう1つのことは、このプログラムは以前に正解を拒否したため、よくわかりません.
これが私の解決策です:
各バケットの前にあるすべてのバケットの合計を計算し、その数の上限をバケットの容量で割って、それらの数をすべて加算します。
例: 6 6 6 6 6 -> 6 12 18 24 30
ceil(6/10) ceil(12/10) ceil(18/10) ceil(24/10) ceil(30/10) = 1 + 2 + 2 + 3 + 3 = 11
それが正しい答えです: 6 6 6 6 6 -> 6 2 10 6 6 -> 0 8 10 6 6 -> 0 8 10 2 10 -> 0 8 2 10 10 -> 0 0 10 10 10 -> 0 0 10 10 0 -> 0 0 10 0 10 -> 0 0 10 0 0 -> 0 0 0 10 0 -> 0 0 0 0 10 -> 0 0 0 0 0 = 11 ステップ
ロジックはL
、特定のバケツの前に 1 リットルの水がある場合、少なくともceil(L/Capacity)
その位置を通過する動きがなければならないということです。これまでに約 30 のテスト ケースを試しましたが、すべてうまくいきました。反例を見つけたと思うたびに、手で何度か試してみると、自分が間違っていることに気づきました。問題は、これが正しい答えだと確信していますが、このようなことを証明する方法がわからないか、単に間違っている可能性があることです。
この答えが正しいかどうか誰か教えてもらえますか?