は(リットルで)異なる容量を持つ3つの容器であります多くの可能性があり、そこに13リットルを分配するのですか? 私はそれらをすべて系統的にリストアップしてブルートフォースを試み、51の可能性の結果を得ました。分布
強引な力がない別の方法がありますか?そして私の解決策も正しいですか?
ありがとうございます! :D
は(リットルで)異なる容量を持つ3つの容器であります多くの可能性があり、そこに13リットルを分配するのですか? 私はそれらをすべて系統的にリストアップしてブルートフォースを試み、51の可能性の結果を得ました。分布
強引な力がない別の方法がありますか?そして私の解決策も正しいですか?
ありがとうございます! :D
あなたはこのように試すことができます:あなたが唯一つの容器を持っている場合は、すべての水を使用して、複数の容器を持っている場合は収まる任意の量を入れて、そのコンテナ
残りの水とコンテナのためのソリューションを組み合わせる:
def divide(liters, containers):
if len(containers) == 1 and containers[0] >= liters:
yield [liters]
elif len(containers) >= 2 and liters <= sum(containers):
first, *rest = containers
for x in range(0, min(liters, first) + 1):
for remaining in divide(liters - x, rest):
yield [x] + remaining
result = list(divide(13, [11, 8, 5]))
print(len(result))
このアルゴリズムは、3つ以上の容器にも使用できます。しかしこれはより効率的にすることができます。重複計算を減らすために、何らかの形式のメモや動的プログラミングを使うことができますが、3つのコンテナはそれほど問題になりません。
(もちろん、これは、水が唯一1リットルの倍数に分割することができることを前提としている。)
単一容器が一度だけ使用することができ、
アイデアは
list
に格納されているコンテナの容量をバックトラックすることです。
言語タグが指定されていないので、私はC++で私のことを教えてくれます。組合せの総数は、answer
変数にあり、containers
は、リストのリストとしてストアされ、変数result
に格納されます。
int answer = 0;
vector<vector<int>> result;
void fillJug(vector<int> list, int index, int cap, vector<int> temp)
{
if(cap == 0)
{
++answer;
result.push_back(temp);
return;
}
if(cap < list[index])
{
return;
}
for(int i= index; i < list.size(); ++i)
{
vector<int> newtemp(temp);
newtemp.push_back(list[i]);
fillJug(list,i + 1,cap - list[i], newtemp);
}
}
容器
[5, 8, 11]
および総容量のため
= 13出力iは1 あろう。e)のコンテナが複数回使用することができます場合は、
fillJug(list,i,cap - list[i], newtemp);
に
を変更
[5, 8]
を使用すると、あなたはここで、 "ブルートフォース" とは何を意味するのですか?可能であれば、3つの容器のすべての充填物を試してみて、それらのどれが最大13個になっているのかを見てください。 –
はい、それは私が試みたものです。 – GionSnow
問題は非常に小さいので、よりスマートな解決方法を考えるのは妥当ではありません。 2つのネストされたループを使用して、それぞれの可能性を試してみてください。 – Henry