前言:每日更新!不断更!,周内一天一题.周末算法精析
✨更新地址:Royeblog
动态规划
背包九讲
状压DP
树形DP
数位DP
✍[题目]:有N件物品,可以放进一个容量为W的背包,第i件物品的体积是w[i];价值是v[i];怎么放使得背包里面的总价值最大?
✍[特点]:每个物品只选择一次or不选
✍[思路]:问题化小,当N=1,很好判断怎么放,N=2,N=3…所以可以确定我们的dp[i] [j]表示在有i件物品,容量为j时的最大价值.
那么状态方程可以写为
❗抱歉写的时候没注意,我这里写的v[i]是体积,w[i]是价值和题写反了
import java.util.Scanner;
public class a01背包 {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[] w=new int[n+1];
int[] v=new int[n+1];
for (int i = 1; i < n+1; i++) {
v[i]=sc.nextInt();
w[i]=sc.nextInt();
}
int[][] dp=new int[n+1][m+1];
for (int i = 1; i < n + 1; i++) {
for (int j = 1; j < m + 1; j++) {
if (j<v[i]){
dp[i][j]=dp[i-1][j];
}else {
dp[i][j]= Math.max(dp[i-1][j],dp[i-1][j-v[i]]+w[i]);
}
}
}
System.out.println(dp[n][m]);
}
}
自己不妨敲一遍,可以去acwing上测试一下题目链接点击前往
✍[题目]:有N种物品,可以放进一个容量为W的背包,第i件物品的体积是w[i];价值是v[i];怎么放使得背包里面的总价值最大?
✍[特点]:每种物品可以多选
✍[思路]:和01背包一个道理,可以将之前的只能放一个加一个循环放多次,对于第i种物品,循环找到最佳k
那么状态方程可以写为
import java.util.Scanner;
public class b完全背包 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[] w = new int[n + 1];
int[] v = new int[n + 1];
for (int i = 1; i < n + 1; i++) {
w[i] = sc.nextInt();
v[i] = sc.nextInt();
}
int[] dp = new int[m + 1];
for (int i = 1; i < n + 1; i++) {
int weight = w[i];
int value = v[i];
for (int j = m; j >= weight; j--) {
for (int k = 0; k * weight <= j; k++) {
dp[j]= Math.max(dp[j],dp[j-k*weight]+k*value);
}
}
}
System.out.println(dp[m]);
}
}
自己不妨敲一遍,可以去acwing上测试一下题目链接点击前往
✍[题目]:有N种物品,可以放进一个容量为W的背包,第i件物品的体积是w[i];价值是v[i];怎么放使得背包里面的总价值最大?
✍[特点]:每种商品有个数限制
import java.util.Scanner;
public class c多重背包 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
int[] w = new int[n + 1];
int[] v = new int[n + 1];
int[] s = new int[n + 1];
for (int i = 1; i < n + 1; i++) {
w[i] = sc.nextInt();
v[i] = sc.nextInt();
s[i] = sc.nextInt();
}
int[] dp = new int[m + 1];
for (int i = 1; i < n + 1; i++) {
int weight = w[i];
int value = v[i];
int num = s[i];
for (int j = m; j >= weight; j--) {
for (int k = 0; k * weight <= j&&k<=num; k++) {
dp[j]= Math.max(dp[j],dp[j-k*weight]+k*value);
}
}
}
System.out.println(dp[m]);
}
}
自己不妨敲一遍,可以去acwing上测试一下题目链接点击前往
点击直达