LintCode-动态规划算法-背包问题
92. 背包问题
描述:在n个物品中挑选若干物品装入背包,最多能装多满?假设背包的大小为m,每个物品的大小为A[i]。
你不可以将物品进行切割。
样例:
样例 1:
输入: [3,4,8,5], backpack size=10
输出: 9
样例 2:
输入: [2,3,5,7], backpack size=12
输出: 12
(背包原始代码)
public class Solution {
/**
* @param m: An integer m denotes the size of a backpack
* @param A: Given n items with size A[i]
* @return: The maximum size
*/
public int backPack(int m, int[] A) {
// write your code here
if(m<=0){
return 0;
}
int n = A.length;
//dp[i][j]:在背包(剩余)容量为j的情况下,前i个物品决策一波儿后得到的最大价值
int[][] dp = new int[n][m+1];
//第0个物品放进0~m的背包容量情况
for(int i=0;i<=m;i++){
dp[0][i] = A[0]<=i?A[0]:0;
}
for(int i=1;i<n;i++){
for(int j=0;j<=m;j++){
dp[i][j]=dp[i-1][j];
if(A[i]<=j){
dp[i][j]=Math.max(dp[i][j],dp[i-1][j-A[i]]+A[i]);
}
}
}
return dp[n-1][m];
}
}
700. 杆子分割
描述:给一个 n 英寸长的杆子和一个包含所有小于 n 的尺寸的价格. 确定通过切割杆并销售碎片可获得的最大值.
样例1:
输入:
[1, 5, 8, 9, 10, 17, 17, 20]
8
输出:22
解释:
长度 | 1 2 3 4 5 6 7 8
--------------------------------------------
价格 | 1 5 8 9 10 17 17 20
切成长度为 2 和 6 的两段。
样例2:
输入:
[3, 5, 8, 9, 10, 17, 17, 20]
8
输出:24
解释:
长度 | 1 2 3 4 5 6 7 8
--------------------------------------------
价格 | 3 5 8 9 10 17 17 20
切成长度为 1 的 8 段。
算法思想:给出的第二个样例,可以看出本题是完全背包问题的变型。所以用完全背包代码可解~~~
(完全背包原始代码)
本题代码:
public class Solution {
/**
* @param prices: the prices
* @param n: the length of rod
* @return: the max value
*/
public int cutting(int[] prices, int n) {
// Write your code here
if (n <= 0||prices==null) {
return 0;
}
int length = prices.length;
int[][] dp = new int[length][n+1];
for (int i = 0; i <= n; i++) {
dp[0][i] = i*prices[0];
}
int max =0;
for (int i = 1; i < length; i++) {
for (int j = 0; j <= n; j++) {
for(int k=0;k<=j/(i+1);k++){
int temp = dp[i-1][j-k*(i+1)]+k*prices[i];
if(temp>max){
max = temp;
}
}
dp[i][j] = max;
max =0;
}
}
return dp[length-1][n];
}
}