为什么这个动态编程代码不正确?

时间:2013-03-02 09:59:44

标签: java dynamic-programming

我正在为家庭作业做出this问题。我使用标准的自下而上动态编程算法解决了这个问题。我的代码显示了我的测试用例的预期结果,但网站说它给出了错误的答案。我无法理解这段代码缺少的地方。请帮帮我。

import java.io.*;
import java.util.*;
class Main300{

public static void main (String[] args) throws java.lang.Exception{
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    int nn = Integer.parseInt(br.readLine());
    for(int j = 0 ; j < nn; j++){
        int n = Integer.parseInt(br.readLine());
        char[][] a = new char[n][n];
        int ki = -1;
        int kj = -1;
        for(int i = 0 ; i < n ; i++){
            String s = br.readLine();
            for(int k = 0 ; k < n; k++){
                a[i][k] = s.charAt(k);
                if(a[i][k] == 'K'){
                    ki = i;
                    kj = k;
                }
            }
        }
        System.out.println(ans(a, ki, kj));
    }
}

private static int ans(char[][] a, int ki, int kj){
    int[][] x = new int[a.length][a.length];
    for(int j = a.length-1; j >= 0; j--){
        for(int i = 0 ; i < a.length; i++){
            if(a[i][j] == 'P'){
                x[i][j]++;
            }
            if(i-2 >= 0 && j+1 <= a.length-1 && a[i-2][j+1] == 'P'){
                x[i][j] += x[i-2][j+1];
            }else if(i-1 >= 0 && j+2 <= a.length-1 && a[i-1][j+2] == 'P'){
                x[i][j] += x[i-1][j+2];
            }else if(i+2 <= a.length-1 && j+1 <= a.length-1 && a[i+2][j+1] == 'P'){
                x[i][j] += x[i+2][j+1];
            }else if(i+1 <= a.length-1 && j+2 <= a.length-1 && a[i+1][j+2] == 'P'){
                x[i][j] += x[i+1][j+2];
            }
        }
    }
    return x[ki][kj];
}
}

2 个答案:

答案 0 :(得分:1)

我会略微修改你的方法。您会发现这对DP解决方案非常有用。这将帮助您编写一个更简单的解决方案,您将自己解决您的WA:)

不是检查边界,而是根据您的关系将表格TAB(代码中的x)放大一点。

TAB[r][c]的值等于它可以从(r, c)

开始捕获的最大卒子数

The White Knight 问题中,看看Knight如何在上方和下方2行,以及右侧2列。因此,请使用TAB[N+4][N+2]代替TAB[N][N]。在这种情况下,使用基值0填充此额外空格。

enter image description here

关系非常简单(您使用4 if-else编码)

TAB[r][c] = max(TAB[r-2][c+1], TAB[r-1][c+2], TAB[r+1][c+2], TAB[r+2][c+1])

如果TAB[r][c](在您的情况下为INP[r][c] == 'P'),当然会增加a

最后,最终解决方案为TAB[ki+2][kj](代码中为ki, kj)。

答案 1 :(得分:1)

以下是错误答案的原因:

a)DP配方将

a[r][c] = max(a[r-2][c+1], a[r-1][c+2], a[r+1][c+2], a[r+2][c+1])

因此您需要验证当前位置的每条路径。您的代码建议您只在一条路径上执行此操作(仅else if's模拟仅通过一条路径)。

b)同样@Vinayak指出,'a [i-2] [j + 1] =='P'将允许你移动到只有那个有棋子的地方,这不一定是真的。您可以考虑一些非常简单的例子来验证这一点。

以下是代码:

import java.io.*;
import java.util.*;

class e1_test{

    public static void main (String[] args) throws java.lang.Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int nn = Integer.parseInt(br.readLine());
        for(int j = 0 ; j < nn; j++){
            int n = Integer.parseInt(br.readLine());char[][] a = new char[n][n];
            int ki = -1;
            int kj = -1;
            for(int i = 0 ; i < n ; i++){
                String s = br.readLine();
                for(int k = 0 ; k < n; k++){
                    a[i][k] = s.charAt(k);
                    if(a[i][k] == 'K'){
                        ki = i;
                        kj = k;
                    }
                }
            }
            System.out.println(ans(a, ki, kj));
        }
    }

    private static int ans(char[][] a, int ki, int kj) {
        int[][] x = new int[a.length][a.length];
        for(int j = a.length-1; j >= 0; j--) {
            for(int i = 0 ; i < a.length; i++) {
                if(a[i][j] == 'P') {
                    x[i][j]++;
                }
                int temp=0;
                //note the changes from else if's to only if's
                //removal of [i-2][j+1] == 'P' condition. 
                if(i-2 >= 0 && j+1 <= a.length-1) {
                    if(temp < x[i-2][j+1])
                        temp = x[i-2][j+1];
                }
                if(i-1 >= 0 && j+2 <= a.length-1) {
                    if(temp < x[i-1][j+2])
                        temp = x[i-1][j+2];
                }
                if(i+2 <= a.length-1 && j+1 <= a.length-1) {
                    if(temp < x[i+2][j+1])
                        temp = x[i+2][j+1];
                }
                if(i+1 <= a.length-1 && j+2 <= a.length-1) {
                    if(temp < x[i+1][j+2])
                        temp = x[i+1][j+2];
                }
                x[i][j] += temp;
            }
        }
        return x[ki][kj];
    }
}