如何使用递归处理SPOJ-Tourist的以下测试用例?

时间:2016-06-10 19:27:54

标签: dynamic-programming

有人可以建议如何处理SPOJ-Tourist问题的以下案例(http://www.spoj.com/problems/TOURIST/)吗?

案例是:

5 5 
.**** 
*###* 
*.*.* 
.#### 
.*.*.

我的实现类似于此示例代码(在How to solve this by recursion?中提到)

const int N 100+5
vector<string> board;

int dp[N][N][N];  // initialize with -1

int calc(int x1, int y1, int  x2) {
    int n=board.size(), m=board[0].size();
    int y2=x1+y1-x2;
    if(x1>=n || x2>=n || y1>=m || y2>=m) return 0;   // out of range
    if(board[x1][y1]=='#' || board[x2][y2]=='#') return 0;  // path blocked so its an invalid move
    if(dp[x1][y1][x2]!=-1) return dp[x1][y1][x2];  // avoid recalculation
    int res=0;
    if(board[x1][y1]=='*') res++;
    if(board[x2][y2]=='*') res++;
    if(board[x1][y1]=='*' && x1==x2 && y1==y2) res=1;  // both tourist on same spot
    int r=calc(x1+1, y1, x2);        // first tourist down second tourist right
    r=max(r, calc(x1+1, y1, x2+1));  // first tourist down second tourist down
    r=max(r, calc(x1, y1+1, x2));    // first tourist right second tourist right
    r=max(r, calc(x1, y1+1, x2+1));  // first tourist right second tourist down
    res+=r;
    dp[x1][y1][x2]=res;  // memoize
    return res;
}

但我想这对上述情况不起作用。 ans应为4,但输出为8。

1 个答案:

答案 0 :(得分:0)

你的电话:

  

calc(x1 + 1,y1,x2 + 1)

似乎是罪魁祸首。因为你的+1x1和{ x2将取消&amp; y2与之前的y2相同。你的病情

  

if(dp [x1] [y1] [x2]!= - 1)返回dp [x1] [y1] [x2];

可以防止无限循环,但会再次计算每个位置的值。

一个简单的解决方案是:发送(x1+1, y1, x2+1)和一个控制信息(x1,y1,x2),而不是发送0(1R-2R),1(1R-2D),2(1D-2R),3(1D-2D)等。然后根据控制信息计算新的(x1, y1)&amp; (x2,y2)