动态规划:用空间代替重复计算
任何动态规划问题都一定对应着一个有重复调用行为的递归
所以动态规划的题目都一定可以从递归入手,逐渐实现动态规划的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| package class066;
import java.util.Arrays;
public class Code02_MinimumCostForTickets {
public static int[] durations = { 1, 7, 30 };
public static int mincostTickets1(int[] days, int[] costs) { return f1(days, costs, 0); }
public static int f1(int[] days, int[] costs, int i) { if (i == days.length) { return 0; } int ans = Integer.MAX_VALUE; for (int k = 0, j = i; k < 3; k++) { while (j < days.length && days[i] + durations[k] > days[j]) { j++; } ans = Math.min(ans, costs[k] + f1(days, costs, j)); } return ans; }
public static int mincostTickets2(int[] days, int[] costs) { int[] dp = new int[days.length]; for (int i = 0; i < days.length; i++) { dp[i] = Integer.MAX_VALUE; } return f2(days, costs, 0, dp); }
public static int f2(int[] days, int[] costs, int i, int[] dp) { if (i == days.length) { return 0; } if (dp[i] != Integer.MAX_VALUE) { return dp[i]; } int ans = Integer.MAX_VALUE; for (int k = 0, j = i; k < 3; k++) { while (j < days.length && days[i] + durations[k] > days[j]) { j++; } ans = Math.min(ans, costs[k] + f2(days, costs, j, dp)); } dp[i] = ans; return ans; }
public static int MAXN = 366;
public static int[] dp = new int[MAXN];
public static int mincostTickets3(int[] days, int[] costs) { int n = days.length; Arrays.fill(dp, 0, n + 1, Integer.MAX_VALUE); dp[n] = 0; for (int i = n - 1; i >= 0; i--) { for (int k = 0, j = i; k < 3; k++) { while (j < days.length && days[i] + durations[k] > days[j]) { j++; } dp[i] = Math.min(dp[i], costs[k] + dp[j]); } } return dp[0]; }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| package class066;
import java.util.Arrays;
public class Code03_DecodeWays {
public static int numDecodings3(String str) { char[] s = str.toCharArray(); int n = s.length; int[] dp = new int[n + 1]; dp[n] = 1; for (int i = n - 1; i >= 0; i--) { if (s[i] == '0') { dp[i] = 0; } else { dp[i] = dp[i + 1]; if (i + 1 < s.length && ((s[i] - '0') * 10 + s[i + 1] - '0') <= 26) { dp[i] += dp[i + 2]; } } } return dp[0]; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| package class066;
public class Code05_UglyNumberII {
public static int nthUglyNumber(int n) { int[] dp = new int[n + 1]; dp[1] = 1; for (int i = 2, i2 = 1, i3 = 1, i5 = 1, a, b, c, cur; i <= n; i++) { a = dp[i2] * 2; b = dp[i3] * 3; c = dp[i5] * 5; cur = Math.min(Math.min(a, b), c); if (cur == a) { i2++; } if (cur == b) { i3++; } if (cur == c) { i5++; } dp[i] = cur; } return dp[n]; }
}
|