问题定义
我有n
容量相同的水桶m
,一个接一个。我可以将水从一个桶倒到它右边的那个。目标是将它们全部倒入另一个容器中,但只能清空最右边的桶。它们每个都有一定的初始水量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,即三步。
示例 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 次移动
我首先尝试使用不同类型的算法(贪婪、动态、回溯等),但似乎都没有。我以为我找到了一个非常直观的解决方案,但检查这些答案的程序告诉我这是错误的,所以我可能错了。另一件事是这个程序以前拒绝了正确的答案,所以我不太确定。
这是我的解决方案:
计算每个桶之前所有桶的总和,然后将该数字的上限除以桶的容量,然后将所有这些数字相加。
例如: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
在某个桶之前有一升水,那么至少必须有ceil(L/Capacity)
经过该位置的移动。到目前为止,我已经尝试了大约 30 个测试用例,它们都奏效了。每次我以为我找到了一个反例,我手动尝试了几次后才意识到我错了。问题是,虽然我很确定这是正确的答案,但我不知道如何证明这样的事情,否则我可能只是错了。
有人可以告诉我这个答案是否正确吗?