1.基本01背包问题
题目链接:01背包基础版
题目:
细节去看背包九讲,主要是注意几个问题
1.通俗写法:
import java.util.Scanner;public class Main {public static void main(String[] args) throws Exception {Scanner sc=new Scanner(System.in);int N=sc.nextInt();int V=sc.nextInt();int[] w=new int[N+1];int[] v=new int[N+1];for(int i=1;i<=N;i++) {v[i]=sc.nextInt();w[i]=sc.nextInt();}sc.close();int[][] f=new int[N+1][V+1];for(int i=1;i<=N;i++) {for(int j=0;j<=V;j++) {f[i][j]=f[i-1][j];if(j-v[i]>=0) {f[i][j]=Math.max(f[i][j], f[i-1][j-v[i]]+w[i]);}}}System.out.println(f[N][V]);}}
2.采用空间压缩和优化常数(就是改1位dp,然后第二个for循环没必要遍历全部的v)
import java.util.Scanner;public class Main {public static void main(String[] args) throws Exception {Scanner sc=new Scanner(System.in);int N=sc.nextInt();int V=sc.nextInt();int[] w=new int[N+1];int[] v=new int[N+1];for(int i=1;i<=N;i++) {v[i]=sc.nextInt();w[i]=sc.nextInt();}sc.close();int[] f=new int[V+1];for(int i=1;i<=N;i++) {//下面这个for循环注意,j>=v[i]这个常数时间优化,因为小于他的就不用走if了,也就不需要改动值了for(int j=V;j>=v[i];j--) {if(j-v[i]>=0) f[j]=Math.max(f[j], f[j-v[i]]+w[i]);}}System.out.println(f[V]);}}
还有一个要点事初始化问题,本题给的是不是恰好,所以初始化全0即可,因为如果不用物品的时候,背包容量就是0,最大值也是0,所以都填0。
2.01背包变形(恰好装满)
例题:题目链接
class Solution {public boolean canPartition(int[] nums) {int sum=0;for(int i=0;i<nums.length;i++){sum+=nums[i];}if(sum%2!=0){return false;}int target=sum/2;boolean[] dp=new boolean[target+1];dp[0]=true;for(int i=0;i<nums.length;i++){for(int j=target;j>=nums[i];j--){dp[j]=dp[j]||dp[j-nums[i]];}}return dp[target];}}
上面是学了背包九讲之后做的,可以在力扣看看没学之前做的,扣了半天初始化,这就是学和不学的区别。。
不管怎么变形,就是看我依赖上面的状态,还有初始化问题。
