我正在为家庭作业做出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];
}
}
答案 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
填充此额外空格。
关系非常简单(您使用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];
}
}