解题思路:
dp[i][j]表示面对第 i 个物品时,最大重量 j 的背包所拥有的最大价值
打表,找出状态转移方程:
if(j<w[i]){ //不拿
dp[i][j]=dp[i-1][j];
}else{ //拿或不拿
dp[i][j]=Math.max(dp[i-1][j], dp[i-1][j-w[i]]+v[i]);
}
参考代码:
方法一:二维dp表
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc=new Scanner(System.in); int n=sc.nextInt(),m=sc.nextInt(); //物品个数、背包最大重量 int[] w=new int[n+1]; int[] v=new int[n+1]; int[][] dp=new int[n+1][m+1]; for(int i=1;i<n+1;i++){ w[i]=sc.nextInt(); v[i]=sc.nextInt(); } for(int i=1;i<n+1;i++){ //第i个物品 for(int j=1;j<m+1;j++){ //重量为j的背包 if(j<w[i]){ //不拿 dp[i][j]=dp[i-1][j]; }else{ //拿或不拿 dp[i][j]=Math.max(dp[i-1][j], dp[i-1][j-w[i]]+v[i]); } } } System.out.print(dp[n][m]); } }
方法二:一维dp表
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc=new Scanner(System.in); int n=sc.nextInt(),m=sc.nextInt(); //物品个数、背包最大重量 int[] w=new int[n+1]; int[] v=new int[n+1]; int[] dp=new int[m+1]; for(int i=1;i<n+1;i++){ w[i]=sc.nextInt(); v[i]=sc.nextInt(); } for(int i=1;i<n+1;i++){ //第i个物品 for(int j=m;j>=1;j--){ //重量为j的背包,要从后往前推,因为从前往后推会把上一条的dp[j-w[i]]记录给覆盖 if(j>=w[i]){ //j<w[i]放不下就不拿不更新dp表,j>=w[i]放得下就更新dp表 dp[j]=Math.max(dp[j], dp[j-w[i]]+v[i]); } } } System.out.print(dp[m]); } }
0.0分
5 人评分
点我有惊喜!你懂得!浏览:1233 |
C语言程序设计教程(第三版)课后习题6.9 (C语言代码)浏览:481 |
不知道哪里错了浏览:1141 |
【亲和数】 (C语言代码)浏览:597 |
C语言程序设计教程(第三版)课后习题3.7 (C语言代码)浏览:509 |
C语言程序设计教程(第三版)课后习题8.3 (C语言代码)浏览:524 |
青年歌手大奖赛_评委会打分 (C语言代码)浏览:2138 |
分解质因数 (C++代码)浏览:1471 |
C语言程序设计教程(第三版)课后习题9.3 (C语言代码)浏览:574 |
C二级辅导-分段函数 (C语言代码)浏览:738 |