798. 背包问题VII
中文English
假设你身上有 n 元,超市里有多种大米可以选择,每种大米都是袋装的,必须整袋购买,给出每种大米的重量,价格以及数量,求最多能买多少公斤的大米
样例
样例 1:
输入: n = 8, prices = [3,2], weights = [300,160], amounts = [1,6]
输出: 640
解释: 全买价格为2的米。
样例 2:
输入: n = 8, prices = [2,4], weight = [100,100], amounts = [4,2 ]
输出: 400
解释: 全买价格为2的米
class Solution:
"""
@param m: the money of you
@param prices: the price of rice[i]
@param weight: the weight of rice[i]
@param amounts: the amount of rice[i]
@return: the maximum weight
"""
def backPackVII(self, m, prices, weight, amounts):
# write your code here
'''
本题a[i][j]表示以j元能买到的前i件物品的最大重量
a[i][j] = max(a[i][j], a[i-1][j-k*prices[i]] + k*weight[i])
0=<k<=amount[i], and k <= j//prices[i]
'''
n = len(prices)
a = [[0 for _ in range(m+1)] for _ in range(n+1)]
prices = [0] + prices
weight = [0] + weight
amounts = [0] + amounts
for i in range(1, n+1):
for j in range(0, m+1):
s = j // prices[i] #j元最多能买多少
for k in range(amounts[i]+1):
'''注意这里max,a[i][j]而不是a[i-1][j],是因为每次都需要和上一次的最大值比,而最
大值保存在a[i][j]中
'''
if j >= k * prices[i]:
#如果k大于最多能买的数量,则不能放入
a[i][j] = max(a[i][j], a[i-1][j-k*prices[i]] + k*weight[i])
return a[n][m]
799. 背包问题VIII
给一些不同价值和数量的硬币。找出这些硬币可以组合在1 ~ n范围内的值的数量
样例
样例 1:
输入:
n = 5
value = [1,4]
amount = [2,1]
输出: 4
解释:
可以组合出1,2,4,5
样例 2:
输入:
n = 10
value = [1,2,4]
amount = [2,1,1]
输出: 8
解释:
可以组合出1-8所有数字。
public class Solution {
/**
* @param n: the value from 1 - n
* @param value: the value of coins
* @param amount: the number of coins
* @return: how many different value
* a[i][j]表示前i个物品是否能组成价值j
a[i][j] = a[i][j] or a[i-1][j-k*value[i]]
注意初始化a[0...n][0]=true
*/
public int backPackVIII(int m, int[] value, int[] amount) {
// write your code here
int n = value.length;
boolean[][] a = new boolean[n+1][m+1];
for (int i = 0; i < n+1; i++){
for (int j = 0; j < m+1; j++){
a[i][j] = false;
}
}
//前i个物品能够组成价值0,都选0个,j=0的时候设置为1
for (int i = 0; i < n+1;i++ ){
a[i][0] = true;
}
for (int i = 1; i < n+1 ;i++ ){
for (int j = 0; j < m+1;j++ ){
for (int k = 0; k < amount[i-1]+1;k++ ){
if (j >= k * value[i-1]){
//只要有一个能组成就可以了,所以是or
a[i][j] = a[i][j] | a[i-1][j - k * value[i-1]];
if(a[i][j]){
break;
}
}
}
}
}
int cnt = 0;
for (int i = 1; i < m+1 ; i++){
if (a[n][i]){
cnt += 1;
}
}
return cnt;
}
}