C 回答错误:戴水肺潜水员SPOJ

C 回答错误:戴水肺潜水员SPOJ,c,algorithm,dynamic-programming,knapsack-problem,C,Algorithm,Dynamic Programming,Knapsack Problem,我在试SPOJ。它基本上是一个0/1的背包 问题陈述:我们被给予N≤1000选择氧气容量、氮气容量和重量分别为O[i]、N[i]和W[i]的储气罐≤21,N≤79,W≤800。我们需要足够的油箱分别为氧气和氮气提供燃料,以完成潜水。找到完成潜水所需的油箱的最小总重量 我已经实现了一个三维动态规划解决方案。但我得到了错误的答案。请帮忙 源代码: int dp[1002][23][81]; // to store subproblems int ox[1002],nt[1002],wt[1002

我在试SPOJ。它基本上是一个0/1的背包

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

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

源代码:

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]);
}
intdp[1002][23][81];//存储子问题
int-ox[1002],nt[1002],wt[1002];//氧:氧;nt:氮;wt=气缸的重量
孔隙溶解(int n,int oxy,int nit){//n:钢瓶数量,oxy:所需氧气;nit:所需氮气

对于(int i=0;i而言,问题在于您为所有使用0个储罐的案例分配了无限重量(成本)——错误地包括
oxy=nit=0
。在这种情况下(即
dp[0][0][0]
),分配的重量应为0,因为您可以使用0个储罐轻松地供应0氧气和0氮气


此错误将导致您的代码错过每个最小解决方案,其中储罐完全满足氧气和氮气需求,没有剩余,因为所有这些决策序列都在
dp[0][0][0]处结束
将最后一个容器添加到当前部分解决方案后的子问题。要解决它,如果在最内部循环中进行测试,则只需颠倒前两个
的顺序。

您应该将整个代码编辑到问题中,虽然删除未使用的标题会使其稍微短一点,但不会太长,而且应该添加一个语言标记。似乎没有使用给定储气罐的单个值初始化数组的步骤。或者这包含在最后的
else
分支中?请详细说明一点递归方程。@Codor
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]);
在这一行中,min()的第二个参数做了这件事。它将包括箱子,其中只包括圆筒。是的,就像背包一样。