完全背包问题 ------ java
2016-11-08 00:38
239 查看
完全背包问题
Description:
有N种物品和一个最大承重为M的背包,每种物品都有无限件可用。
求解将哪些物品装入背包可使这些物品的费用总和不超过背包最大承重,且价值总和最大。
每种物品具有 Vi价值,Wi的重量,数量无限。
Input:
第一行输入两个整数,N,M。
余下N行每行输入两个整数,Wi和Vi。
Output:
输出最大价值。
样例:
Input:
3 7
3 4
4 5
2 3
Output:
7
首先,众所周知,这是一个动态规划的基本问题。
然后,一个比较简单的状态转移方程。
dp[i+1][j] = max{dp[i][j-k*w[i]]+k*v[i]|0<=k && j >= k*w[i]}
这个方程对应 solve_1();的方法。
dp[i][j] 代表从前i种物品中挑选总重量不超过i时总价值的最大值。
然后这个方程呢,有一些比较坑爹的地方,他做了很多重复计算。
其中关于空间复杂度的优化。
Description:
有N种物品和一个最大承重为M的背包,每种物品都有无限件可用。
求解将哪些物品装入背包可使这些物品的费用总和不超过背包最大承重,且价值总和最大。
每种物品具有 Vi价值,Wi的重量,数量无限。
Input:
第一行输入两个整数,N,M。
余下N行每行输入两个整数,Wi和Vi。
Output:
输出最大价值。
样例:
Input:
3 7
3 4
4 5
2 3
Output:
7
首先,众所周知,这是一个动态规划的基本问题。
然后,一个比较简单的状态转移方程。
dp[i+1][j] = max{dp[i][j-k*w[i]]+k*v[i]|0<=k && j >= k*w[i]}
这个方程对应 solve_1();的方法。
dp[i][j] 代表从前i种物品中挑选总重量不超过i时总价值的最大值。
举个例子,拿上面的当数据,求dp[3][4]. 就需要比较dp[2][4]和dp[2][4-1*w[3]]+1*v[3]的大小。dp[3][4]就是大的那一个了。 其中dp[2][4]就是dp[2][4-0*w[3]]+0*v[3].
然后这个方程呢,有一些比较坑爹的地方,他做了很多重复计算。
假设我们已知dp[i][j-1*w[i]]的时候,那我们就已经知道了:从前i种物品中挑选总重量不超过i时总价值的最大值。 那么这就意味着,下面的方程永远成立 dp[i][j-1*w[i]] >= max{dp[i][j-k*w[i]]+k*v[i]|k>=2&&k*w[i]<=j} 然后我们就不需要考虑k>1的所有情况了. 所以就有了新的状态转移方程: dp[i+1][j]=max(dp[i][j],dp[i+1][j-w[i]]+v[i])。这个也就是solve_2(); (要注意,dp[i][j-2*w[i]]+2*v[i]这个东西,是在dp[i+1][j-w[i]]+v[i])中被计算的。)
其中关于空间复杂度的优化。
这个嘛,solve_3有轮子阿! 其实就是改一改solve_2的... 具体观察方程,就会发现需要用到的只是i和i+1那一层,那就可以以奇数为1,偶数为0来实现辣。就这么简单。
import java.util.Scanner; public class Beibao { static int[][] dp; static int n,W; static int[] w,v; public static void main(String[] args) { Scanner input = new Scanner(System.in); n = input.nextInt(); W = input.nextInt(); w = new int[n+1]; v = new int[n+1]; for(int i = 0 ; i<n ; i++){ w[i] = input.nextInt(); v[i] = input.nextInt(); } solve_1(); solve_2(); } static void solve_1(){ dp = new int[n+1][W+1]; for(int i = 0 ; i<n ; i++ ){ for(int j = 0 ; j<=W ; j++){ for(int k = 0 ; k*w[i] <= j ; k++){ dp[i+1][j] = Math.max( dp[i+1][j] , dp[i][j-k*w[i]] + k*v[i]); } } } System.out.println(dp [W]); } static void solve_2(){ dp = new int[n+1][W+1]; for(int i = 0 ; i<n ; i++){ for(int j = 0 ; j <= W ; j++){ if( j < w[i] ){ dp[i+1][j] = dp[i][j]; }else{ dp[i+1][j] = Math.max(dp[i][j], dp[i+1][j-w[i]]+v[i]); } } } System.out.println(dp [W]); } static void solve_3(){ dp = new int[2][W+1]; for(int i = 0 ; i<n ; i++){ for(int j = 0 ; j <= W ; j++){ if( j < w[i] ){ dp[(i+1)%2][j] = dp[i%2][j]; }else{ dp[(i+1)%2][j] = Math.max(dp[i%2][j], dp[(i+1)%2][j-w[i]]+v[i]); } } } System.out.println(dp[1][W]); } }
相关文章推荐
- 完全背包问题(Java实现)
- 背包问题(01背包和完全背包)java求解
- 背包九讲之完全背包问题 Java实现 滑动数组
- 完全背包问题,java解法
- 完全背包问题,java解法
- 动态规划算法分析及实例——求解完全背包问题(java实现)
- 完全背包问题-含优化
- Piggy-Bank-完全背包问题
- 背包问题详解:01背包、完全背包、多重背包
- F - Piggy-Bank 完全背包问题
- 完全背包问题(贪心)
- 完全背包问题
- 01背包问题和完全背包问题
- 【算法系列学习】[kuangbin带你飞]专题十二 基础DP1 F - Piggy-Bank 【完全背包问题】
- 动态规划求解背包问题(JAVA实现)
- 动态规划之背包问题01--java实现
- 0-1背包问题(java版)
- 背包问题-动态规划-JAVA
- 背包问题小总结 习题(动态规划01背包(第k优解)完全背包,多重背包)acm杭电HDU2639,HDU2602,HDU1114,HDU2191
- UVA 147 Dollars ( 完全背包+求解方案数精度问题)