把一个棋盘放到第一象限,棋盘的最左下角是(0,0)位置,整个棋盘是横坐标上又9条线,纵坐标上有10条线的区域,给定3个参数x,y,k
返回“马”从(0,0)位置出发,必须走k步到(x,y)的方法数有多少种
递归函数:
含义:当前来到了(x,y)这个位置,返回走rest步移动到(a,b)位置的方法数,所以主函数应该这样调用
初始位置(0,0),剩余步数k,目标位置(a,b)
终止条件:当x,y的位置越界了,直接返回0
放rest==0时,如果移动到了目标位置,则返回这一种方法发,否则返回0.
//当前位置x,y
//剩余rest步
//目标位置a,b
//10*9
public static int process1(int x,int y,int rest,int a,int b){
if(x<0||x>9||y<0||y>8){
return 0;
}
if(rest==0){
return (x==a&&y==b)?1:0;
}
int ways=process1(x+2,y+1,rest-1,a,b);
ways+=process1(x+1,y+2,rest-1,a,b);
ways+=process1(x-1,y+2,rest-1,a,b);
ways+=process1(x-2,y+1,rest-1,a,b);
ways+=process1(x-2,y-1,rest-1,a,b);
ways+=process1(x-1,y-2,rest-1,a,b);
ways+=process1(x+1,y-2,rest-1,a,b);
ways+=process1(x+2,y-1,rest-1,a,b);
return ways;
}
public static int jump2(int a,int b,int k){
//x的变化范围是0~9
//y的变化范围是0~8
//rest的变化范围是0~k
int[][][] dp=new int[10][9][k+1];
dp[a][b][0]=1;
for (int rest = 1; rest <=k ; rest++) {
for(int x=0;x<=9;x++){
for (int y = 0; y <=8; y++) {
int ways=pick(dp,x+2,y+1,rest-1);
ways+=pick(dp,x+1,y+2,rest-1);
ways+=pick(dp,x-1,y+2,rest-1);
ways+=pick(dp,x-2,y+1,rest-1);
ways+=pick(dp,x-2,y-1,rest-1);
ways+=pick(dp,x-1,y-2,rest-1);
ways+=pick(dp,x+1,y-2,rest-1);
ways+=pick(dp,x+2,y-1,rest-1);
dp[x][y][rest]=ways;
}
}
}
return dp[0][0][k];
}
public static int pick(int[][][] dp,int x,int y,int rest){
if(x<0||x>9||y<0||y>8){
return 0;
}
return dp[x][y][rest];
}