我的动态编程方法在哪里出错了?

时间:2016-02-25 16:32:12

标签: c++ algorithm dynamic-programming

我正在尝试解决这个问题http://www.spoj.com/problems/BYTESM2/

这是我到目前为止尝试的代码,

#include <iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int a[101][101],Table[101][101]={0};
int pickStones(int i,int j,int n,int m,int sum)
{
    int k,l,p;
    int stones=0;
    if(i>n||j>m||j<0)
    return 0;
    else if(i==n)
    return Table[i][j]=sum;
    else
    {
        if(Table[i][j]==0)
        {
            if(Table[i+1][j]==0)
        Table[i+1][j]=pickStones(i+1,j,n,m,sum+a[i][j]);
        if(Table[i+1][j-1]==0)
        Table[i+1][j-1]=pickStones(i+1,j-1,n,m,sum+a[i][j]);
        if(Table[i+1][j+1]==0)
        Table[i+1][j+1]=pickStones(i+1,j+1,n,m,sum+a[i][j]);
        stones=max(Table[i+1][j],Table[i+1][j-1]);
        stones=(max(stones,Table[i+1][j+1]));
        Table[i][j]=stones;
        }
        return Table[i][j];
    }
}
int main() {
    int t,n,m,l=0,h=0,max;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        scanf("%d",&a[i][j]);
        max=a[0][0];
        for(int i=0;i<m;i++)
        if(a[0][i]>max)
        {
            max=a[0][i];
            l=0;h=i;
        }
        printf("%d\n",pickStones(l,h,n,m,0));
    }
    return 0;
}

如果我摆脱动态编程Table[][]数组并将`pickStones()的结果存储在变量中并将问题实现为普通递归我得到正确答案但我不知道重叠子问题在哪里在此以及如何存储它们以避免再次计算。

1 个答案:

答案 0 :(得分:0)

您想要一个解决方案,或解释为什么您的代码无法运行? 无论如何,我会先给我的AC代码。

#include<bits/stdc++.h>
using namespace std;

int w[200][200] = {0}, dp[200][200] = {0};
int t,r,c;
int main(){
    cin >> t;
    while(t--){
        cin >> r >> c;
        memset(w,0,sizeof(w)); memset(dp,0,sizeof(dp));
        for(int i=1; i<=r ;i++) for(int j=1; j<=c; j++) { 
            cin >> w[i][j]; dp[1][j] = w[1][j];
        }
        for(int i=2; i<=r; i++) for(int j=1; j<=c; j++) 
            dp[i][j] = w[i][j] + max(dp[i-1][j-1], max(dp[i-1][j], dp[i-1][j+1]));
        int ans = 0;
        for(int i=1; i<=c;i++) ans = max(ans, dp[r][i]);
        cout << ans << endl;
    }
}

代码

 max=a[0][0];
 for(int i=0;i<m;i++)
     if(a[0][i]>max)
     {
         max=a[0][i];
         l=0;h=i;
     }

您是否在第一行选择最大石块列? 这可能并非总是如此。