象棋马的走向--暴力递归转动态规划7

棋盘的最左下角是(0,0)位置
那么整个棋盘就是横坐标上9条线、纵坐标上10条线的区域
给你三个 参数 x,y,k
返回“马”从(0,0)位置出发,必须走k步
最后落在(x,y)上的方法数有多少种?
public class 象棋马的走向 {
    /**
     * @param x 棋盘的x点
     * @param y 棋盘的y点
     * @param k 走几步
     * @return 方法数
     */
    public static int f1(int x, int y, int k) {
        return process1(0, 0, x, y, k);
    }

    public static int process1(int x1, int y1, int x, int y, int k) {
        if (x1 < 0 || x1 > 9 || y1 < 0 || y1 > 8) {
            return 0;
        }
        if (k == 0) {
            return ( x1 == x && y1 == y) ? 1 : 0;
        }
        return process1(x1 + 2, y1 + 1, x, y, k - 1)
                + process1(x1 + 1, y1+ 2, x, y, k - 1)
                + process1(x1 - 2, y1 + 1, x, y, k - 1)
                + process1(x1 - 1, y1 + 2, x, y, k - 1)
                + process1(x1 - 2, y1 - 1, x, y, k - 1)
                + process1(x1 - 1, y1 - 2, x, y, k - 1)
                + process1(x1 + 1, y1 - 2, x, y, k - 1)
                + process1(x1 + 2, y1 - 1, x, y, k - 1);
    }

    public static int f2(int x, int y, int k) {
        int[][][] dp = new int[10][9][k + 1];
        dp[x][y][0] = 1;
        for (int i = 1; i <= k; i++) {
            for (int j = 0; j < 10; j++) {
                for (int l = 0; l < 9; l++) {
                    int ans = pick(dp, j + 2, l + 1, i - 1);
                    ans += pick(dp, j + 1, l + 2, i - 1);
                    ans += pick(dp, j - 2, l + 1, i - 1);
                    ans += pick(dp, j - 1, l + 2, i - 1);
                    ans += pick(dp, j - 2, l - 1, i - 1);
                    ans += pick(dp, j - 1, l - 2, i - 1);
                    ans += pick(dp, j + 1, l - 2, i - 1);
                    ans += pick(dp, j + 2, l - 1, i - 1);
                    dp[j][l][i] = ans;
                }
            }
        }
        return dp[0][0][k];
    }

    public static int pick(int[][][] dp, int x, int y, int k) {
        if (x < 0 || x > 9 || y < 0 || y > 8) {
            return 0;
        }
        return dp[x][y][k];
    }

    public static void main(String[] args) {
        System.out.println(f1(7, 7, 10));
        System.out.println(f2(7, 7, 10));
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值