动态规划背包问题总结
Posted 知道什么是码怪吗?
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划背包问题总结相关的知识,希望对你有一定的参考价值。
目录
01背包问题
java题解
朴素做法
import java.util.Scanner;
public class Main
public static void main(String[] args)
Scanner input = new Scanner(System.in);
int n = input.nextInt();//n件物品
int m = input.nextInt();//m个体积
int[] v = new int[1010];//每件物品的体积
int[] w = new int[1010];//每件物品的价值
int[][] result = new int[1010][1010];//result[i][j]表示从前i件物品中选总体积为j的物品的最大价值
for (int i = 1; i <= n; i++) //接收数据
v[i] = input.nextInt();//体积
w[i] = input.nextInt();//价值
/*-----------------------------------------------------*/
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
result[i][j] = result[i - 1][j];
if (j >= v[i])//如果当前背包的体积大于了这件物品的体积,取一次max看是放入这件物品后总价值大还是不放价值大
result[i][j] = Math.max(result[i][j], result[i - 1][j - v[i]] + w[i]);
/*-----------------------------------------------------*/
System.out.println(result[n][m]);
滚动数组空间优化
import java.util.Scanner;
public class Main
public static void main(String[] args)
Scanner input = new Scanner(System.in);
int n = input.nextInt();//n件物品
int m = input.nextInt();//m个体积
int[] v = new int[1010];//每件物品的体积
int[] w = new int[1010];//每件物品的价值
int[] result = new int[1010];//result[i]表示体积为选体积为i的最大价值,会随着循环的遍历不停刷新
for (int i = 1; i <= n; i++) //接收数据
v[i] = input.nextInt();//体积
w[i] = input.nextInt();//价值
/*-----------------------------------------------------*/
for (int i = 1; i <= n; i++)
for (int j = m; j >= v[i]; j--) //滚动数组,从大到小的遍历,比j小的result值相当于i-1层的最大价值
result[j] = Math.max(result[j], result[j - v[i]] + w[i]);
/*-----------------------------------------------------*/
System.out.println(result[m]);
完全背包问题
朴素做法
import java.util.Scanner;
public class Main
public static void main(String[] args)
Scanner input = new Scanner(System.in);
int n = input.nextInt();//n件物品
int m = input.nextInt();//m个体积
int[] v = new int[1010];//每件物品的体积
int[] w = new int[1010];//每件物品的价值
int[][] result = new int[1010][1010];//记录结果
for (int i = 1; i <= n; i++) //接收数据
v[i] = input.nextInt();//体积
w[i] = input.nextInt();//价值
/*-----------------------------------------------------*/
for (int i = 1; i <= n; i++)
for (int j = 0; j <= m; j++)
for (int k = 0; k * v[i] <= j; k++)
result[i][j] = Math.max(result[i][j], result[i - 1][j - k * v[i]] + k * w[i]);
/*-----------------------------------------------------*/
System.out.println(result[n][m]);
时间空间优化
import java.util.Scanner;
public class Main
public static void main(String[] args)
Scanner input = new Scanner(System.in);
int n = input.nextInt();//n件物品
int m = input.nextInt();//m个体积
int[] v = new int[1010];//每件物品的体积
int[] w = new int[1010];//每件物品的价值
int[] result = new int[1010];
for (int i = 1; i <= n; i++) //接收数据
v[i] = input.nextInt();//体积
w[i] = input.nextInt();//价值
/*-----------------------------------------------------*/
for (int i = 1; i <= n; i++)
for (int j = v[i]; j <= m; j++) //因为当j小于v[i]的时候,放不进去,可以不用遍历
result[j]=Math.max(result[j],result[j-v[i]]+w[i]);
/*-----------------------------------------------------*/
System.out.println(result[m]);
多重背包问题
朴素做法
import java.util.Scanner;
public class Main
public static int size = 1010;
public static void main(String[] args)
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int m = input.nextInt();
int[][] dp = new int[size][size];
int[] v = new int[size];
int[] w = new int[size];
int[] c = new int[size];
for (int i = 1; i <= n; i++)
v[i] = input.nextInt();
w[i] = input.nextInt();
c[i] = input.nextInt();
/*-----------------------------------------------------*/
for (int i = 1; i <= n; i++)
for (int j = 0; j <= m; j++)
for (int k = 0; k <= c[i]; k++)
if (k * v[i] <= j)
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - k * v[i]] + k * w[i]);
/*-----------------------------------------------------*/
System.out.println(dp[n][m]);
时间空间优化
优化方式和01背包类似
import java.util.Scanner;
public class Main
public static int size = 1010;
public static void main(String[] args)
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int m = input.nextInt();
int[] dp = new int[size];
int[] v = new int[size];
int[] w = new int[size];
int[] c = new int[size];
for (int i = 1; i <= n; i++)
v[i] = input.nextInt();
w[i] = input.nextInt();
c[i] = input.nextInt();
/*-----------------------------------------------------*/
for (int i = 1; i <= n; i++)
for (int j = m; j >= v[i]; j--)
for (int k = 0; k <= c[i]; k++)
if (k * v[i] <= j)
dp[j] = Math.max(dp[j], dp[j - k * v[i]] + k * w[i]);
/*-----------------------------------------------------*/
System.out.println(dp[m]);
分组背包问题
朴素做法
import java.util.Scanner;
public class Main
public static int size = 1010;
public static void main(String[] args)
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int m = input.nextInt();
int[][] dp = new int[size][size];
int[] c = new int[size];
int[][] v = new int[size][size];//v[i][j]表示第i组第j件物品的体积
int[][] w = new int[size][size];//w[i][j]表示第i组第j件物品的价值
for (int i = 1; i <= n; i++)
c[i] = input.nextInt();
for (int j = 0; j < c[i]; j++)
v[i][j] = input.nextInt();
w[i][j] = input.nextInt();
/*-----------------------------------------------------*/
for (int i = 1; i <= n; i++)
for (int j = 0; j <= m; j++)
dp[i][j] = dp[i - 1][j];//如果不选当前种类的物品
for (int k = 0; k < c[i]; k++)
if (v[i][k] <= j)
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - v[i][k]] + w[i][k]);
/*-----------------------------------------------------*/
System.out.println(dp[n][m]);
空间优化
import java.util.Scanner;
public class Main
public static int size = 1010;
public static void main(String[] args)
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int m = input.nextInt();
int[] dp = new int[size];
int[] c = new int[size];
int[][] v = new int[size][size];//v[i][j]表示第i组第j件物品的体积
int[][] w = new int[size][size];//w[i][j]表示第i组第j件物品的价值
for (int i = 1; i <= n; i++)
c[i] = input.nextInt();
for (int j = 0; j < c[i]; j++)
v[i][j] = input.nextInt();
w[i][j] = input.nextInt();
/*-----------------------------------------------------*/
for (int i = 1; i <= n; i++)
for (int j = m; j >= 0; j--)
for (int k = 0; k < c[i]; k++)
if (v[i][k] <= j)
dp[j] = Math.max(dp[j], dp[j - v[i][k]] + w[i][k]);
/*-----------------------------------------------------*/
System.out.println(dp[m]);
以上是关于动态规划背包问题总结的主要内容,如果未能解决你的问题,请参考以下文章