动态编程SPOJ问题SCUBADIV

时间:2011-07-27 18:46:50

标签: c algorithm dynamic-programming

我试图从SPOJ解决这个问题,这是一个动态编程问题,但是我在查看递归步骤时遇到了麻烦。我相信它类似于背包,但这里有两个氧和氮的限制。

以下是链接:http://www.spoj.pl/problems/SCUBADIV/

2 个答案:

答案 0 :(得分:5)

我认为这应该有效:

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循环必须从最大值向下移动到当前柱面的值,否则您允许多次使用柱面。

问题限制非常小,我认为这应该有效。

答案 1 :(得分:4)

@IVlad非常好的答案,谢谢:)

但是有一个问题:

应删除以下内容:

dp[oxygen[i], nitrogen[i]] = weight[i] for each cylinder i and inf otherwise

然后使用它:

dp[0][0] = 0 and infinity everywhere else

前一个语句不是有效的基本情况,因为它允许使用两次柱面。

怎么样?

最外层循环的不变量是在 Ñ 在迭代(k)中,我们尝试每个i,j来计算可以达到的最小重量,以获得至少i氧和j氮 仅使用1到N个柱面(每个使用一次)

考虑以下测试案例,其中需要2个氧气和2个氮气,我们有2个气瓶,其中1个牛1 1 1重量,另一个是2牛2镍50重量

2 2

2

1 1 1

2 2 50

答案应该是50,因为我们不能两次使用第一个气缸。

我声称错误的基本情况将在我们开始循环之前填充d [1] [1] = 1。 然后循环以k = 0开始(使用第一个圆柱并查看它是否有助于任何条目),然后d [2] [2]将等于d [2-1] [2-1] +1 = d [1] [1] + 1 = 2

最终答案将是2个单位的重量,因为第一个气缸由于基础情况而被使用了两次,这是不正确的。