贴一个java的解法
查看原帖
贴一个java的解法
512864
ice1618977554楼主2024/12/12 14:37

思路还是DP,用dp(i,j)表示起点到(i,j)的路径数,用备忘录memo消除重叠子问题

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Arrays;

/**
 * @author ice
 * @Description: P1002 [NOIP2002 普及组] 过河卒
 * @date 2024/12/12
 */
public class Main {

    // 消除重叠子问题
    long[][] memo;

    private int hX, hY;
    private int destX, destY;
    public static void main(String[] args) throws IOException {
        Main p1002 = input();

        // base case
        p1002.memo = new long[p1002.destX + 1][p1002.destY + 1];
        for (int i = 0; i < p1002.destX + 1; i++) {
            Arrays.fill(p1002.memo[i], -1);
        }
        p1002.memo[0][0] = 1;
        int[][] dir = new int[][]{{1, 2}, {1, -2},{-1, 2}, {-1, -2}, {2, 1}, {2, -1}, {-2, 1}, {-2, -1}};
        p1002.memo[p1002.hX][p1002.hY] = 0;
        for (int i = 0; i < dir.length; i++) {
            int x = p1002.hX + dir[i][0];
            int y = p1002.hY + dir[i][1];
            if (!p1002.exceedBorder(x, y)) {
                p1002.memo[x][y] = 0;
            }
        }

        // dp
        System.out.println(p1002.dp(p1002.destX, p1002.destY));
        return;
    }

    // dp(i, j)表示从起点到(i, j)的路径数
    private long dp(int i, int j) {
        if (exceedBorder(i, j)) {
            return 0;
        }
        if (memo[i][j] != -1) {
            return memo[i][j];
        }
        return memo[i][j] = dp(i - 1, j) + dp(i, j - 1);
    }

    private boolean exceedBorder(int x, int y) {
        if (x > this.destX || y > this.destY || x < 0 || y < 0) {
            return true;
        }
        return false;
    }

    private static Main input() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StreamTokenizer st = new StreamTokenizer(br);
        Main p1002 = new Main();
        for (int i = 0; i < 2; i++) {
            st.nextToken();
            int x = (int)st.nval;
            st.nextToken();
            int y = (int)st.nval;
            if (i == 0) {
                p1002.destX = x;
                p1002.destY = y;
            } else {
                p1002.hX = x;
                p1002.hY = y;
            }
        }
        return p1002;
    }
}
2024/12/12 14:37
加载中...