错误答案:潜水员SPOJ

时间:2015-01-27 07:22:36

标签: c algorithm dynamic-programming knapsack-problem

我在SPOJ上尝试this problem。它基本上是0/1背包。

问题陈述:我们给出N≤1000选择具有氧气容量,氮容量和重量 O [i],N [i]和W [i]的空气罐 O≤21,N≤79,W≤800。我们需要足够的油箱分别为 t氧气和氮气提供燃油以完成潜水。找到所需坦克的最小总重量以完成潜水。

我已经实现了一个三维动态编程解决方案。但我得到了错误的答案。请帮忙。

源代码:

int dp[1002][23][81];   // to store subproblems
int ox[1002],nt[1002],wt[1002]; // ox: oxygen; nt: nitrogen; wt = weight of cylinder

void solve(int n, int oxy, int nit){ // n: no. of cylinders, oxy: oxygen required; nit: nitrogen required
  for(int i = 0; i <=n; ++i)
    for(int j = 0; j <= oxy; ++j)
      for(int k = 0; k <= nit; ++k){
        if(i == 0)
          dp[i][j][k] = INF;
        else if(j == 0 && k == 0)
          dp[i][j][k] = 0;
        else
          dp[i][j][k] = min(dp[i-1][j][k], dp[i-1][max(j-ox[i], 0)][max(k-nt[i], 0)] + wt[i]);
      }
  printf("%d\n", dp[n][oxy][nit]);
}

请帮忙。 Complete Source Code

1 个答案:

答案 0 :(得分:2)

问题是你要为使用0坦克的所有案件分配无限重量(成本) - 包括错误地,oxy = nit = 0的情况。在这种情况下(即dp[0][0][0]),分配的重量应为0,因为使用0罐可以非常舒适地提供0氧气和0氮气。

这个错误会导致你的代码错过每个最小的解决方案,其中正好覆盖了氧气和氮气的要求而没有遗留下来,因为所有这些决策序列都以{{1}结束将最后一个槽添加到当前部分解决方案后的子问题。要修复它,您需要做的就是颠倒最内层循环中前两个dp[0][0][0]测试的顺序。