C++ scubadiv spoj中的WA(自上而下的dp)

C++ scubadiv spoj中的WA(自上而下的dp),c++,algorithm,dynamic-programming,C++,Algorithm,Dynamic Programming,我被困在获取WA的路上 我已经看到了这个问题的许多自下而上的实现。我的自上而下的实现与备忘录无关,没有它也可以正常工作。我怎样才能纠正它 #include<cstdio> #include<cstring> #include<iostream> #define INF 0x7FFFFFFF using namespace std; int o,n,num,ox[2000],nt[2000],wt[2000]; int dp[2000][2000]; i

我被困在获取WA的路上

我已经看到了这个问题的许多自下而上的实现。我的自上而下的实现与备忘录无关,没有它也可以正常工作。我怎样才能纠正它

#include<cstdio>
#include<cstring>
#include<iostream>

#define INF 0x7FFFFFFF

using namespace std;

int o,n,num,ox[2000],nt[2000],wt[2000];
int dp[2000][2000];

int dive(int index,int oxygen,int nitrogen,int weight) {
    if(dp[oxygen][nitrogen]!=-1) return dp[oxygen][nitrogen];
    int &ret=dp[oxygen][nitrogen];
    if(oxygen>=o&&nitrogen>=n) {
        ret=weight; 
        return ret;
    }
    if(index==num) {
        ret=INF;
        return ret;
    }
    ret= min(dive(index+1,oxygen+ox[index],nitrogen+nt[index],weight+wt[index]),dive(index+1,oxygen,nitrogen,weight));  
    return ret;
}

main() {
    int c;
    scanf("%d",&c);
    while(c--) {
        memset(dp,-1,sizeof(dp));
        scanf("%d%d",&o,&n);
        scanf("%d",&num);
        for(int i=0;i<num;++i) {
            scanf("%d%d%d",&ox[i],&nt[i],&wt[i]);
        }
        printf("%d\n",dive(0,0,0,0));
    }
    return 0;
}
#包括
#包括
#包括
#定义INF 0x7FFFFFFF
使用名称空间std;
int o,n,num,ox[2000],nt[2000],wt[2000];
int dp[2000][2000];
内部潜水(内部指数、内部氧气、内部氮气、内部重量){
如果(dp[氧][氮]!=-1)返回dp[氧][氮];
int&ret=dp[氧][氮];
如果(氧>=o和氮>=n){
ret=重量;
返回ret;
}
如果(索引==num){
ret=INF;
返回ret;
}
ret=min(潜水(指数+1,氧+氧[指数],氮+氮[指数],重量+重量[指数]),潜水(指数+1,氧,氮,重量));
返回ret;
}
main(){
INTC;
scanf(“%d”、&c);
而(c--){
memset(dp,-1,sizeof(dp));
scanf(“%d%d”,&o,&n);
scanf(“%d”和&num);
对于(int i=0;i请尝试以下测试:

1
21 79
5
1 1 800
1 1 800
1 1 800
1 1 800
17 75 800

在我看来,正确的答案应该是
800*5=4000
对吗?您的程序输出。

这也给出了错误的答案:(有人能检查一下吗

    #include<iostream>
    using namespace std;
    int swap( int &a,int &b)
    {
       int temp=a;
       a=b;
       b=temp;
    }
    int min(int a, int b)
    {
    if(a<b)return a;else return b;
    }
    int max(int a,int b) 
    {
    if(a>b)return a;else return b;
    }
    int minweight(int ans[][22][80],int arr[][3],int n,int oxy,int nit)
    {
     int prev=0,curr=1;

    for(int i=1;i<=n;i++)
    {

        for(int j=0;j<=21;j++)
            for(int k=0;k<=79;k++)
                ans[curr][j][k]=min( ans[prev][j][k], arr[i][2]+ans[prev][max(0,j-arr[i][0])][max(0,k-arr[i][1])]);
        swap(curr,prev);
}


        return ans[n&1][oxy][nit];
    }
   int main()
   {
    int cases;
    cin>>cases;

    while(cases--)
    {
        int oxy,nit;
        cin>>oxy>>nit;
        int n;
        cin>>n;
        int arr[n+1][3];
        for(int i=1;i<=n;i++)
        {
            cin>>arr[i][0]>>arr[i][1]>>arr[i][2];
        }   
        int ans[2][22][80];

            for(int j=0;j<oxy+1;j++)
                for(int k=0;k<nit+1;k++)
                    ans[0][j][k]=9999;
            ans[0][0][0]=0;

        cout<<minweight(ans,arr,n,oxy,nit);
    }
#包括
使用名称空间std;
内部交换(内部和a、内部和b)
{
内部温度=a;
a=b;
b=温度;
}
最小整数(整数a,整数b)
{
如果(ab)返回a,否则返回b;
}
整数最小重量(整数ans[][22][80],整数arr[][3],整数n,整数oxy,整数nit)
{
int prev=0,curr=1;
对于(inti=1;i>oxy>>nit;
int n;
cin>>n;
国际航空公司[n+1][3];
对于(int i=1;i>arr[i][0]>>arr[i][1]>>arr[i][2];
}   
[2][22][80];;

对于(int j=0;j非常感谢您的反馈。我想我的记忆技术是错误的,因为当我评论“如果(dp[氧气][氮气]!=-1)返回dp[氧气][氮气];”然后我似乎得到了正确的答案。关于记忆的任何帮助??你的记忆技术是正确的。你的dp有问题。状态不仅由氮和氧的量定义,还由迄今为止累积的重量定义。你可能会遇到两个不同重量的相同情况你不需要通过重量n递归。将其从参数列表中删除,并在每次迭代时将其作为局部变量保留。你的意思是我应该使用3D数组吗?我是动态编程新手。你能提供一些伪代码来说明如何实现它吗@Ivaylo@user3108270是的,我可以提供伪代码,我可以提供完整的解决方案,但我不会像这样这是练习的一个非常重要的部分。不过,我会给你一些提示:根据经验法则,任何作为参数传递给dp并在进行递归调用时可能更改的内容都应该是数组中的一个维度。但是,你不需要传递权重,因为它与子问题的解决方案无关。在这种情况下,你应该创建一个索引新建维度并从递归参数中移除权重(如上所述,在函数中用局部变量替换它)。