我正在尝试解决来自SPOJ的问题,这是一个动态规划问题,但是我很难想象递归步骤。我相信它类似于背包问题,但这里有两个约束条件:氧气和氮气。
我正在尝试解决来自SPOJ的问题,这是一个动态规划问题,但是我很难想象递归步骤。我相信它类似于背包问题,但这里有两个约束条件:氧气和氮气。
dp[i, j] = minimum weight needed such that we have i litres of oxygen and j litres
of nitrogen
dp[0, 0] = 0 and inf everywhere else
for each read cylinder k do
for i = maxTotalOxygen down to oxygen[k] do
for j = maxTotalNitrogen down to nitrogen[k] do
dp[i, j] = min(dp[i, j], <- do not take cylinder k
dp[i - oxygen[k], j - nitrogen[k]] + weight[k]) <- take cylinder k
Answer is the minimum dp[i, j] such that i >= RequiredOxygen and j >= RequiredNitrogen.
for
循环必须从最大值向下到当前气缸的值,否则您将允许一个气缸被多次使用。[i, j]
时使用了圆柱体 k
,则也可以使用它来计算 [i-oxygen[k],j-oxygen[k]]
,这意味着你对 [i, j]
使用了两次,而 SPOJ 问题不允许这样做(尽管允许这样做的问题也是完全有效的)。 - IVladx
,其中 oxygen[x] = 2
且 nitrogen[x] = 4
来查找 dp [3,5]
,那么如果您按升序遍历循环,还可以使用它来查找 dp [5,9]
,这是不希望的,因为这意味着您在 dp [5,9]
中使用了两次它。 - IVladmaxTotalOxygen
是所有氧气罐价值之和,通过加入一个含有大量氧氮的重型气罐,可以创建一个非常庞大的搜索空间。 看起来应该有一条更有效的路线,因为很多搜索空间不需要被探索(类似于三重嵌套的for循环)。 - Richard@IVlad非常好的回答,谢谢:)
然而有一个陷阱:
以下内容应该被删除:
dp[oxygen[i], nitrogen[i]] = weight[i] for each cylinder i and inf otherwise
并使用此内容:
dp[0][0] = 0 and infinity everywhere else