【问题标题】:WA in scubadiv spoj (top down dp)scubadiv spoj 中的 WA(自上而下 dp)
【发布时间】:2013-12-16 17:55:06
【问题描述】:

我被困在this question 获得西澳。

我已经看到了这个问题的许多自下而上的实现。我的自上而下的实现不适用于 memoization,没有它也可以正常工作。我该如何纠正它?

#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;
}

【问题讨论】:

    标签: c++ algorithm dynamic-programming


    【解决方案1】:

    试试这个测试:

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

    在我看来正确答案应该是800 * 5 = 4000 对吧?你的程序输出something else。

    【讨论】:

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

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

        #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);
        }
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-14
      • 2016-04-26
      • 1970-01-01
      • 2014-07-04
      • 2016-11-11
      • 1970-01-01
      • 2021-09-11
      • 1970-01-01
      相关资源
      最近更新 更多