目录
LintCode 炼码物品大小不重复的填满背包的方案数
LintCode 炼码 物品大小存在重复情况
LintCode 炼码不重复的组合个数
完全背包_牛客题霸_牛客网
LintCode 炼码物品大小不重复的填满背包的方案数
描述给出 n 个物品, 以及一个数组, nums[i]
代表第i
个物品的大小, 保证大小均为正数并且没有重复, 正整数 target
表示背包的大小, 找到能填满背包的方案数。每一个物品可以使用无数次
class Solution {
public:
int backPackIV(vector<int> &nums, int target) {
// write your code here
int n = nums.size();
vector<int> dp(target+1);
dp[0]=1;
for(int i = 0; i < n; ++i)
{
for(int j = nums[i]; j <= target; ++j)
{
dp[j] += dp[j-nums[i]];
}
}
return dp[target];
}
};
LintCode 炼码 物品大小存在重复情况
class Solution {
public:
/**
* @param nums: an integer array and all positive numbers
* @param target: An integer
* @return: An integer
*/
int backPackV(vector<int> &nums, int target) {
// Write your code here
vector<int> dp(target + 1);
dp[0] = 1;
for (auto a : nums) {
for (int i = target; i >= a; --i) {
dp[i] += dp[i - a];
}
}
return dp.back();
}
};
LintCode 炼码不重复的组合个数
class Solution {
public:
int backPackVI(vector<int> &nums, int target) {
// write your code here
vector<int> dp(target+1);
dp[0] =1;
for (int i = 1; i <= target; i++) {
for (int num : nums) {
if (num <= i) {
dp[i] += dp[i - num];
}
}
}
return dp[target];
}
};
完全背包_牛客题霸_牛客网
描述
你有一个背包,最多能容纳的体积是V。
现在有n种物品,每种物品有任意多个,第i种物品的体积为vivi ,价值为wiwi。
(1)求这个背包至多能装多大价值的物品?
(2)若背包恰好装满,求至多能装多大价值的物品?
数据范围: 1≤v,vi,wi≤1000 1≤v,vi,wi≤1000
示例1
输入:6,2,[[5,10],[3,1]]
返回值:[10,2]
示例2
输入:8,3,[[3,10],[9,1],[10,1]]
返回值:[20,0]
说明:无法恰好装满背包。
示例3
输入:13,6,[[13,189],[17,360],[19,870],[14,184],[6,298],[16,242]]
返回值:[596,189]
说明:可以装5号物品2个,达到最大价值298*2=596,若要求恰好装满,只能装1个1号物品,价值为189.
问题1和问题2的求解过程基本一致 ,不同的是在动态规划初始化数组时,在求解问题1时其所对应的动态规划数组全部为0,在求解问题2时其所对应的动态规划数组只有第一个元素为0其余的为负无穷。之所以将动态规划数组里的元素设为负无穷,是为了进行阻断。在从前至后推进时如果在填充了当前元素后还有剩余空间,那么之前扫描过的其他元素若不能恰好填满剩余空间,则这个元素将无法被成功填充(表征为:负无穷加上一个常数还是负无穷),即这种情况将会被阻断。
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param v int整型
* @param n int整型
* @param nums int整型vector<vector<>>
* @return int整型vector
*/
vector<int> knapsack(int m, int n, vector<vector<int> >& nums) {
// write code here
vector<int> dp(m+1, 0);
vector<int> b(m+1, INT_MIN);
b[0] = 0;
vector<int> v(n);
vector<int> w(n);
for(int i = 0; i < n; ++i)
{
v[i] = (nums[i][0]);
w[i] = (nums[i][1]);
}
for(int i = 0; i < n; ++i)
{
for(int j = v[i]; j <= m; j++)
{
dp[j] = max(dp[j], dp[j-v[i]]+w[i]);
b[j] = max(b[j], b[j-v[i]]+w[i]);
}
}
vector<int> res(2);
res[0] = dp[m];
res[1] = b[m]>0?b[m]:0;
return res;
}
};