// 先遍历物品,后遍历重量 for (int i = 1; i < N; i++) { for (int v = 0; v <= V; v++) { // F [i, v] ← max{F [i − 1, v], F [i − 1, v − Ci] + Wi} // F[i][v] = MAX(F[i - 1][v], F[i - 1][v - cost[i]] + value[i]); int bufang = dp[i - 1][v]; dp[i][v] = bufang; if (v >= cost[i]) { int fang = dp[i - 1][v - cost[i]] + value[i]; dp[i][v] = MAX(bufang, fang); } } }
for (int i = 0; i < N; i++) { for (int j = 0; j <= V; j++) { printf("%d\t", dp[i][j]); } printf("\n"); } printf("%d\n", dp[N - 1][V]); }
voidO1Package_N_plus_1(){
int dp[N + 1][V + 1];
// 使用0个物品的价值为0 for (int i = 0; i <= V; i++) { dp[0][i] = 0; }
// 先遍历物品,后遍历重量 for (int i = 1; i <= N; i++) { for (int v = 0; v <= V; v++) { dp[i][v] = dp[i - 1][v]; //当重量不够装i时,价值为装i-1的价值, //此步骤以备i+1时使用(下一个i循环) if (v >= cost[i - 1]) { dp[i][v] = MAX(dp[i - 1][v], dp[i - 1][v - cost[i - 1]] + value[i - 1]); } } }
for (int i = 0; i <= N; i++) { for (int j = 0; j <= V; j++) { printf("%d\t", dp[i][j]); } printf("\n"); } printf("%d\n", dp[N][V]); }
voidO1Package_N_plus_1_origin(){
int dp[N + 1][V + 1];
// 使用0个物品的价值为0 for (int i = 0; i <= V; i++) { dp[0][i] = 0; }
// 先遍历物品,后遍历重量 for (int i = 0; i < N; i++) { for (int v = 0; v <= V; v++) { // 1. 当物品大于承重,物品不会放到背包,价值等于不放此物品时的情况 // 即使物品小于承重,说明物品会放到背包。提前多赋值一次也是允许的 dp[i + 1][v] = dp[i][v]; if (v >= cost[i]) { dp[i + 1][v] = MAX(dp[i][v], dp[i][v - cost[i]] + value[i]); } } }
for (int i = 0; i <= N; i++) { for (int j = 0; j <= V; j++) { printf("%d\t", dp[i][j]); } printf("\n"); } printf("%d\n", dp[N][V]); }
voidO1Package_one_array_n(){
int dp[V + 1];
// 使用0个物品的价值为0 for (int i = 0; i <= V; i++) { dp[i] = 0; }
// 先遍历物品,后遍历重量 for (int i = N - 1; i >= 0; i--) { for (int v = V; v >= cost[i]; v--) { int bufang = dp[v]; int fang = dp[v - cost[i]] + value[i]; dp[v] = MAX(bufang, fang); } }
// 0容量的价值为0, 合法 for (int i = 0; i < cost[0]; i++) { dp[0][i] = 0; }
// 初始化当包承重大于物品0重量的情况 for (int i = cost[0]; i <= V; i++) { // 当只装物品0时,包的价值就是物品0的价值 dp[0][i] = i / cost[0] * value[0]; }
// 先遍历物品,后遍历重量 for (int i = 1; i < N; i++) { for (int v = 0; v <= V; v++) { dp[i][v] = dp[i - 1][v]; //当重量不够装i时,价值为装i-1的价值, //此步骤以备i+1时使用(下一个i循环) for (int k = 1; k <= v / cost[i]; k++) { dp[i][v] = MAX(dp[i - 1][v], dp[i - 1][v - k * cost[i]] + k * value[i]); } } }
for (int i = 0; i < N; i++) { for (int j = 0; j <= V; j++) { printf("%d\t", dp[i][j]); } printf("\n"); } printf("%d\n", dp[N - 1][V]); }
voidCompletePackage_use_n_plus_1(){
int dp[N + 1][V + 1];
// 0容量的价值为0, 合法 for (int i = 0; i <= V; i++) { dp[0][i] = 0; }
// 先遍历物品,后遍历重量 for (int i = 1; i <= N; i++) { for (int v = 0; v <= V; v++) { dp[i][v] = dp[i - 1][v]; //当重量不够装i时,价值为装i-1的价值, //此步骤以备i+1时使用(下一个i循环) for (int k = 1; k <= v / cost[i-1]; k++) { dp[i][v] = MAX(dp[i - 1][v], dp[i - 1][v - k * cost[i-1]] + k * value[i-1]); } } }
for (int i = 0; i <= N; i++) { for (int j = 0; j <= V; j++) { printf("%d\t", dp[i][j]); } printf("\n"); } printf("%d\n", dp[N][V]); }
voidCompletePackage_use_one_array_no_reverse_V(){
int dp[V + 1];
// 0容量的价值为0, 合法 for (int i = 0; i <= V; i++) { dp[i] = 0; }
// 先遍历物品,后遍历重量 for (int i = 1; i <= N; i++) { for (int v = 0; v <= V; v++) { for (int k = 1; k <= v / cost[i-1]; k++) { dp[v] = MAX(dp[v], dp[v - k * cost[i-1]] + k * value[i-1]); } } }
// 0容量的价值为0, 合法 for (int i = 0; i <= V; i++) { dp[i] = 0; }
// 先遍历物品,后遍历重量 for (int i = 1; i <= N; i++) { for (int v = V; v <= cost[i-1]; v--) { for (int k = 1; k <= v / cost[i-1]; k++) { dp[v] = MAX(dp[v], dp[v - k * cost[i-1]] + k * value[i-1]); } } }