两个人玩游戏,有几个数字【2,100,30,5】只能拿最左或者最右的,最后看谁哪的分数高。
前面有暴力递归的代码
// 动态规划public static int win2(int[] arr) {if (arr == null || arr.length == 0) {return 0;}int[][] f = new int[arr.length][arr.length];int[][] s = new int[arr.length][arr.length];for (int j = 0; j < arr.length; j++) {f[j][j] = arr[j];for (int i = j - 1; i >= 0; i--) {f[i][j] = Math.max(arr[i] + s[i + 1][j], arr[j] + s[i][j - 1]);s[i][j] = Math.min(f[i + 1][j], f[i][j - 1]);}}return Math.max(f[0][arr.length - 1], s[0][arr.length - 1]);}
三维表
象棋棋盘上标一个点(x,y),让马跳到这个点,而且还得跳k步。
public class HorseJump {public static int getWays(int x, int y, int step) {return process(x, y, step);}// 潜台词:从(0,0)位置出发// 要去往(x,y)位置,必须跳step步// 返回方法数public static int process(int x, int y, int step) {if (x < 0 || x > 8 || y < 0 || y > 9) {return 0;}if (step == 0) {return (x == 0 && y == 0) ? 1 : 0;}// 要到达的位置不越界,也有步数可以跳return process(x - 1, y + 2, step - 1)+ process(x + 1, y + 2, step - 1)+ process(x + 2, y + 1, step - 1)+ process(x + 2, y - 1, step - 1)+ process(x + 1, y - 2, step - 1)+ process(x - 1, y - 2, step - 1)+ process(x - 2, y - 1, step - 1)+ process(x - 2, y + 1, step - 1);}// 动态规划 严格表结构public static int dpWays(int x, int y, int step) {if (x < 0 || x > 8 || y < 0 || y > 9 || step < 0) {return 0;}int[][][] dp = new int[9][10][step + 1];dp[0][0][0] = 1;for (int h = 1; h <= step; h++) {for (int r = 0; r < 9; r++) {for (int c = 0; c < 10; c++) {dp[r][c][h] += getValue(dp, r - 1, c + 2, h - 1);dp[r][c][h] += getValue(dp, r + 1, c + 2, h - 1);dp[r][c][h] += getValue(dp, r + 2, c + 1, h - 1);dp[r][c][h] += getValue(dp, r + 2, c - 1, h - 1);dp[r][c][h] += getValue(dp, r + 1, c - 2, h - 1);dp[r][c][h] += getValue(dp, r - 1, c - 2, h - 1);dp[r][c][h] += getValue(dp, r - 2, c - 1, h - 1);dp[r][c][h] += getValue(dp, r - 2, c + 1, h - 1);}}}return dp[x][y][step];}public static int getValue(int[][][] dp, int row, int col, int step) {if (row < 0 || row > 8 || col < 0 || col > 9) {return 0;}return dp[row][col][step];}public static void main(String[] args) {int x = 7;int y = 7;int step = 10;System.out.println(getWays(x, y, step));System.out.println(dpWays(x, y, step));}}
给一个N*M大小的表格,bob在(x,y)的位置,如果bob出了界就会死,一个k表示bob能走几步,他每一步等概率上下左右随机走,求他活下来的概率
public class BobDie {public static String bob1(int N, int M, int i, int j, int K) {long all = (long) Math.pow(4, K);long live = process(N, M, i, j, K);long gcd = gcd(all, live);return String.valueOf((live / gcd) + "/" + (all / gcd));}public static long process(int N, int M, int row, int col, int rest) {if (row < 0 || row == N || col < 0 || col == M) {return 0;}if (rest == 0) {return 1;}long live = process(N, M, row - 1, col, rest - 1);live += process(N, M, row + 1, col, rest - 1);live += process(N, M, row, col - 1, rest - 1);live += process(N, M, row, col + 1, rest - 1);return live;}public static long gcd(long m, long n) {return n == 0 ? m : gcd(n, m % n);}public static String bob2(int N, int M, int i, int j, int K) {int[][][] dp = new int[N + 2][M + 2][K + 1];for (int row = 1; row <= N; row++) {for (int col = 1; col <= M; col++) {dp[row][col][0] = 1;}}for (int rest = 1; rest <= K; rest++) {for (int row = 1; row <= N; row++) {for (int col = 1; col <= M; col++) {dp[row][col][rest] = dp[row - 1][col][rest - 1];dp[row][col][rest] += dp[row + 1][col][rest - 1];dp[row][col][rest] += dp[row][col - 1][rest - 1];dp[row][col][rest] += dp[row][col + 1][rest - 1];}}}long all = (long) Math.pow(4, K);long live = dp[i + 1][j + 1][K];long gcd = gcd(all, live);return String.valueOf((live / gcd) + "/" + (all / gcd));}public static void main(String[] args) {int N = 10;int M = 10;int i = 3;int j = 2;int K = 5;System.out.println(bob1(N, M, i, j, K));System.out.println(bob2(N, M, i, j, K));}}
arr里都是正数,没有重复值,每一个值代表一种货币,每一种都可以用无限张,最终要找零钱数是aim,找零方法数返回
// 暴力递归
public static int process (int arr[], int index,int rest) {
if (index == arr.length) {
return rest == 0 ? 1 : 0;
}
// arr[index] 0张 1张。。。 不要超过rest的钱数
int result = 0;
for (int zhang = 0; zhang * arr[index] < rest; zhang++) {
result += process(arr, index + 1, rest - zhang * arr[index]);
}
return result;
}
// 动态规划
public static int way (int[] arr, int aim) {
if (arr == null || arr.length == 0) {
return 0;
}
int N = arr.length;
int[][] dp = new int[N + 1][aim + 1];
dp[N][0] = 1;
for (int index = N - 1; index >= 0; index--) {
for (int rest = 0; rest <= aim; rest++) {
int ways = 0;
for (int zhang = 0; arr[index] * zhang <= rest; zhang++) {
ways += dp[index + 1][rest - arr[index] * zhang];
}
dp[index][rest] = ways;
}
}
return dp[0][aim];
}
上一题在用动态规划求的时候,会产生一个枚举行为



public static int way (int[] arr, int aim) {
if (arr == null || arr.length == 0) {
return 0;
}
int N = arr.length;
int[][] dp = new int[N + 1][aim + 1];
dp[N][0] = 1;
for (int index = N - 1; index >= 0; index--) {
for (int rest = 0; rest <= aim; rest++) {
dp[index][rest] = dp[index + 1][rest];
if (rest - arr[index] >= 0) {
dp[index][rest] += dp[index][rest - arr[index]];
}
}
}
return dp[0][aim];
}
