pull/3/head
Leo 5 years ago
parent ffd83ca8cc
commit ec42fcb28c

@ -24,12 +24,12 @@ public class KillMonster {
}
private static long process(int hp, int m, int rest) {
if (rest == 0) {
return hp <= 0 ? 1 : 0;
}
if (hp <= 0) {
return (long) Math.pow(m + 1, rest);
}
if (rest == 0) {
return hp == 0 ? 1 : 0;
}
int ans = 0;
for (int i = 0; i <= m; i++) {
ans += process(hp - i, m, rest - 1);
@ -40,4 +40,72 @@ public class KillMonster {
}
static class Dp {
public static double kill(int n, int m, int k) {
if (n < 1 || m < 1 || k < 1) {
return 0;
}
long[][] dp = new long[n + 1][k + 1];
dp[0][0] = 1;
for (int hp = 1; hp <= n; hp++) {
for (int rest = 1; rest <= k; rest++) {
dp[0][rest] = (long) Math.pow(m + 1, rest);
long ans = 0;
for (int i = 0; i <= m; i++) {
if (hp - i <= 0) {
ans += (long) Math.pow(m + 1, rest - 1);
} else {
ans += dp[hp - i][rest - 1];
}
}
dp[hp][rest] = ans;
}
}
return dp[n][k] / Math.pow(m + 1, k);
}
}
static class OptDp{
public static double kill(int n, int m, int k) {
if (n < 1 || m < 1 || k < 1) {
return 0;
}
long[][] dp = new long[n + 1][k + 1];
dp[0][0] = 1;
for (int hp = 1; hp <= n; hp++) {
for (int rest = 1; rest <= k; rest++) {
dp[0][rest] = (long) Math.pow(m + 1, rest);
dp[hp][rest] = dp[hp][rest - 1] + dp[hp-1][rest];
if (hp - m - 1 >=0) {
dp[hp][rest] -= dp[hp - m - 1][rest - 1];
}else{
dp[hp][rest] -= (long) Math.pow(m + 1, rest - 1);
}
}
}
return dp[n][k] / Math.pow(m + 1, k);
}
}
public static void main(String[] args){
int NMax = 10;
int MMax = 10;
int KMax = 10;
int testTime = 200;
System.out.println("测试开始");
for (int i = 0; i < testTime; i++) {
int N = (int) (Math.random() * NMax);
int M = (int) (Math.random() * MMax);
int K = (int) (Math.random() * KMax);
double ans1 = Recursion.kill(N, M, K);
double ans2 = Dp.kill(N, M, K);
double ans3 = OptDp.kill(N, M, K);
if (ans1 != ans2 || ans1 != ans3) {
System.out.println("Oops!");
break;
}
}
System.out.println("测试结束");
}
}

@ -0,0 +1,140 @@
package leo.class22;
import class22.Code02_MinCoinsNoLimit;
/**
* @author Leo
* @ClassName MinCoinsNoLimit
* @DATE 2021/1/15 1:39
* @Description
*
* arraim
*
* aim
*/
public class MinCoinsNoLimit {
static class Recursion{
public static int minCoins(int[] arr, int aim) {
return process(arr, aim, 0);
}
private static int process(int[] arr, int rest, int i) {
if (i == arr.length) {
return rest == 0 ? 0 : Integer.MAX_VALUE;
}
int ans = Integer.MAX_VALUE;
for (int z = 0; z * arr[i] <= rest; z++) {
int next = process(arr, rest - z * arr[i], i + 1);
if (next != Integer.MAX_VALUE) {
ans = Math.min(ans, next + z);
}
}
return ans;
}
}
static class Dp {
public static int minCoins(int[] arr, int aim) {
if (aim == 0) {
return 0;
}
int n = arr.length;
int[][] dp = new int[n + 1][aim + 1];
dp[n][0] = 0;
for (int i = 1; i <= aim; i++) {
dp[n][i] = Integer.MAX_VALUE;
}
for (int i = n - 1; i >= 0; i--) {
for (int rest = 0; rest <= aim; rest++) {
int ans = Integer.MAX_VALUE;
for (int z = 0; z * arr[i] <= rest; z++) {
int next = dp[i + 1][rest - z * arr[i]];
if (next != Integer.MAX_VALUE) {
ans = Math.min(ans, next + z);
}
}
dp[i][rest] = ans;
}
}
return dp[0][aim];
}
}
static class OptDp{
public static int minCoins(int[] arr, int aim) {
if (aim == 0) {
return 0;
}
int n = arr.length;
int[][] dp = new int[n + 1][aim + 1];
dp[n][0] = 0;
for (int i = 1; i <= aim; i++) {
dp[n][i] = Integer.MAX_VALUE;
}
for (int i = n - 1; i >= 0; i--) {
for (int rest = 0; rest <= aim; rest++) {
dp[i][rest] = dp[i + 1][rest];
if (rest - arr[i] >= 0 && dp[i][rest - arr[i]] != Integer.MAX_VALUE) {
dp[i][rest] = Math.min(dp[i][rest], dp[i][rest - arr[i]] + 1);
}
}
}
return dp[0][aim];
}
}
// 为了测试
public static int[] randomArray(int maxLen, int maxValue) {
int N = (int) (Math.random() * maxLen);
int[] arr = new int[N];
boolean[] has = new boolean[maxValue + 1];
for (int i = 0; i < N; i++) {
do {
arr[i] = (int) (Math.random() * maxValue) + 1;
} while (has[arr[i]]);
has[arr[i]] = true;
}
return arr;
}
// 为了测试
public static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
// 为了测试
public static void main(String[] args) {
int maxLen = 20;
int maxValue = 30;
int testTime = 300000;
System.out.println("功能测试开始");
for (int i = 0; i < testTime; i++) {
int N = (int) (Math.random() * maxLen);
int[] arr = randomArray(N, maxValue);
int aim = (int) (Math.random() * maxValue);
int ans1 = Recursion.minCoins(arr, aim);
int ans2 = Dp.minCoins(arr, aim);
int ans3 = OptDp.minCoins(arr, aim);
if (ans1 != ans2 || ans1 != ans3) {
System.out.println("Oops!");
printArray(arr);
System.out.println(aim);
System.out.println("--0---");
System.out.println(ans1);
System.out.println(ans2);
System.out.println(ans3);
break;
}
}
System.out.println("功能测试结束");
}
}
Loading…
Cancel
Save