完全背包问题 ------ java
来源:互联网 发布:c语言cout 编辑:程序博客网 时间:2024/05/15 23:45
完全背包问题
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[n][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[n][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]); }}
0 0
- 完全背包问题 ------ java
- 背包问题(01背包和完全背包)java求解
- 背包问题(01背包和完全背包)java求解
- 完全背包问题(Java实现)
- 背包问题-完全背包-背包问题
- 01背包 完全背包问题
- 背包问题2:完全背包
- 01背包+完全背包问题
- nyoj311完全背包(完全背包问题)
- 完全背包问题
- 完全背包问题
- 完全背包问题
- 完全背包问题
- 完全背包问题
- P02: 完全背包问题
- 完全背包问题、、、
- P02: 完全背包问题
- 完全背包问题
- 我带你去哪里 XI
- Android Studio实战 - 编辑器操作
- 深度学习框架Caffe学习笔记(2)-MNIST手写数字识别例程
- 获取本机浏览器列表
- HDU ACM 11 2083 简易版之最短距离
- 完全背包问题 ------ java
- x86下的C函数调用惯例
- EL表达式获取值栈数据的源码分析
- ios 编写UIControl子类
- 关于jsp的那点事
- 工程师成长之路:工作1-3年工程师如何突破瓶颈期?--lgg201
- Lucene 6.0中BooleanQuery
- Unity3d和服务器交互
- python_scapy铸造,发送数据包