动态规划SPOJ问题SCUBADIV

动态规划SPOJ问题SCUBADIV,c,algorithm,dynamic-programming,C,Algorithm,Dynamic Programming,我试图从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 cyli

我试图从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.
dp[i,j]=需要的最小重量,以便我们有i升氧气和j升氧气
氮元素
dp[0,0]=0和inf在其他地方
对于每个读取气缸k do
对于i=maxTotalOxygen向下至氧[k]do
对于j=maxTotal氮气至氮气[k]do
dp[i,j]=最小值(dp[i,j],=所需氮。
请注意,的
循环必须从最大值向下移动到当前圆柱体的值,否则允许圆柱体多次使用


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

@IVlad回答得很好,谢谢:)

然而,有一个陷阱:

应删除以下内容:

dp[oxygen[i], nitrogen[i]] = weight[i] for each cylinder i and inf otherwise
用这个代替:

dp[0][0] = 0 and infinity everywhere else
前一个语句不是有效的基本情况,因为它允许圆柱体使用两次

怎么做

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

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

2.2

二,

11

2520

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

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


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

那么,你的问题是什么?你试过什么?我不明白为什么循环必须向下。如果它是增加的,它应该有同样的效果,对吗?@user866098-不,如果它是增加的,那么如果你在计算某个
[i,j]
时使用圆柱体
k
k
也可以用来计算
[i-氧[k],j-氧[k]
,所以这意味着你在
[i,j]
中使用它两次,SPOJ问题不允许这样做(尽管允许这样做的问题也是完全有效的)。@User866098-尝试在一个小测试上手动运行它。例如,如果您使用某个气缸
x
,其中
氧气[x]=2
氮气[x]=4
来查找
dp[3,5]
,您也可以使用它来查找
dp[5,9]
如果您在for循环中上升,您不想这样做,因为这意味着您在
dp[5,9]中使用了两次
。初始值不应该是0而不是无穷大吗?因为:dp[5,9]=min(dp[5,9],dp[3,5]+重量[k])。如果dp[3,5]最初是无穷大,那么inf+weight[k]将是错误的,对吗?@user866098-不,我认为无穷大是好的。这意味着您不知道
dp[3,5]
的答案。如果将其设置为0,则可能会出现
dp[5,9]=weight[k]
,这是错误的。对于未初始化的值,它需要为无穷大。事实上,不需要初始化,它将在运行主循环时发生。