|
|
package 第03期.mca_09;
|
|
|
|
|
|
public class Test {
|
|
|
|
|
|
public static int f(int n) {
|
|
|
if (n == 1) {
|
|
|
return 1;
|
|
|
}
|
|
|
if (n == 2) {
|
|
|
return 1;
|
|
|
}
|
|
|
// n > 2
|
|
|
return f(n - 1) + f(n - 2);
|
|
|
}
|
|
|
|
|
|
public static int f2(int n) {
|
|
|
int[] dp = new int[n + 1];
|
|
|
return p2(n, dp);
|
|
|
}
|
|
|
|
|
|
public static int p2(int i, int[] dp) {
|
|
|
if (i == 1) {
|
|
|
return 1;
|
|
|
}
|
|
|
if (i == 2) {
|
|
|
return 1;
|
|
|
}
|
|
|
// i > 2
|
|
|
if (dp[i] != 0) {
|
|
|
return dp[i];
|
|
|
}
|
|
|
int ans = p2(i - 1, dp) + p2(i - 2, dp);
|
|
|
dp[i] = ans;
|
|
|
return ans;
|
|
|
}
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
int n = 7;
|
|
|
// 1 1 2 3 5 8 13
|
|
|
System.out.println("菲数列第 " + n + " 项,为" + f(n));
|
|
|
}
|
|
|
|
|
|
// 彻底暴力
|
|
|
public static int knapsack1(int[] w, int[] v, int bag) {
|
|
|
// 0...... bag
|
|
|
// 返回最大价值
|
|
|
return process(w, v, 0, bag);
|
|
|
}
|
|
|
|
|
|
// i....... 货自由选择,背包的剩余载重是j
|
|
|
// 返回最大价值
|
|
|
public static int process(int[] w, int[] v, int i, int j) {
|
|
|
if (j < 0) {
|
|
|
// 剩余载重是负数!???
|
|
|
// 说明之前的选择有错,返回-1表示无效
|
|
|
return -1;
|
|
|
}
|
|
|
// j >= 0;
|
|
|
if (i == w.length) {
|
|
|
// 没货了!
|
|
|
return 0;
|
|
|
}
|
|
|
// 背包j >= 0
|
|
|
// 有货!
|
|
|
// 可能性1,不要当前的货
|
|
|
int p1 = process(w, v, i + 1, j);
|
|
|
// 可能性2,要当前的货
|
|
|
int p2 = 0;
|
|
|
int next2 = process(w, v, i + 1, j - w[i]);
|
|
|
if (next2 != -1) {
|
|
|
p2 = next2 + v[i];
|
|
|
}
|
|
|
return Math.max(p1, p2);
|
|
|
}
|
|
|
|
|
|
// 记忆化搜索
|
|
|
// 货物数量n <= 1000
|
|
|
// 背包容量bag <= 1000
|
|
|
public static int knapsack2(int[] w, int[] v, int bag) {
|
|
|
int n = w.length;
|
|
|
int[][] dp = new int[n][bag + 1];
|
|
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
for (int j = 0; j <= bag; j++) {
|
|
|
dp[i][j] = -2;
|
|
|
}
|
|
|
}
|
|
|
return process2(w, v, 0, bag, dp);
|
|
|
}
|
|
|
|
|
|
// i....... 货自由选择,背包的剩余载重是j
|
|
|
// 返回最大价值
|
|
|
public static int process2(int[] w, int[] v, int i, int j, int[][] dp) {
|
|
|
if (j < 0) {
|
|
|
return -1;
|
|
|
}
|
|
|
if (i == w.length) {
|
|
|
return 0;
|
|
|
}
|
|
|
if (dp[i][j] != -2) {
|
|
|
return dp[i][j];
|
|
|
}
|
|
|
int p1 = process2(w, v, i + 1, j, dp);
|
|
|
int p2 = 0;
|
|
|
int next2 = process2(w, v, i + 1, j - w[i], dp);
|
|
|
if (next2 != -1) {
|
|
|
p2 = next2 + v[i];
|
|
|
}
|
|
|
int ans = Math.max(p1, p2);
|
|
|
dp[i][j] = ans;
|
|
|
return ans;
|
|
|
}
|
|
|
|
|
|
public static int knapsack3(int[] w, int[] v, int bag) {
|
|
|
int n = w.length;
|
|
|
int[][] dp = new int[n + 1][bag + 1];
|
|
|
// dp[n][...] = 0
|
|
|
for (int i = n - 1; i >= 0; i--) {
|
|
|
// 每个格子依赖下一行的,两个位置的值
|
|
|
for (int j = 0; j <= bag; j++) {
|
|
|
// dp[i][j]
|
|
|
int p1 = dp[i + 1][j];
|
|
|
int p2 = 0;
|
|
|
if (j - w[i] >= 0) {
|
|
|
p2 = v[i] + dp[i + 1][j - w[i]];
|
|
|
}
|
|
|
dp[i][j] = Math.max(p1, p2);
|
|
|
}
|
|
|
}
|
|
|
return dp[0][bag];
|
|
|
}
|
|
|
|
|
|
public static int knapsack4(int[] w, int[] v, int bag) {
|
|
|
int n = w.length;
|
|
|
int[] dp = new int[bag + 1];
|
|
|
// 脑中[n][...] = 0
|
|
|
for (int i = n - 1; i >= 0; i--) {
|
|
|
// 每个格子依赖下一行的,两个位置的值
|
|
|
for (int j = bag; j >= 0; j--) {
|
|
|
// 0 1 2 3 4 5 6
|
|
|
// <-
|
|
|
int p1 = dp[j];
|
|
|
int p2 = 0;
|
|
|
if (j - w[i] >= 0) {
|
|
|
p2 = v[i] + dp[j - w[i]];
|
|
|
}
|
|
|
dp[j] = Math.max(p1, p2);
|
|
|
}
|
|
|
}
|
|
|
// 第0行的值
|
|
|
return dp[bag];
|
|
|
}
|
|
|
|
|
|
}
|