You are given two non-negative integer arrays price and tastiness, both arrays have the same length n. You are also given two non-negative integers maxAmount and maxCoupons.
For every integer i in range [0, n - 1]:
price[i] describes the price of ith fruit.
tastiness[i] describes the tastiness of ith fruit.
You want to purchase some fruits such that total tastiness is maximized and the total price does not exceed maxAmount.
Additionally, you can use a coupon to purchase fruit for half of its price (rounded down to the closest integer). You can use at most maxCoupons of such coupons.
Return the maximum total tastiness that can be purchased.
Input: price =[10,20,20], tastiness =[5,8,8], maxAmount =20, maxCoupons =1Output: 13Explanation: It is possible to make total tastiness 13in following way:- Buy first fruit without coupon, so that total price =0+10 and total tastiness =0+5.- Buy second fruit with coupon, so that total price =10+10 and total tastiness =5+8.- Do not buy third fruit, so that total price =20 and total tastiness =13.It can be proven that 13is the maximum total tastiness that can be obtained.
Example 2:
1
2
3
4
5
6
7
Input: price =[10,15,7], tastiness =[5,8,20], maxAmount =10, maxCoupons =2Output: 28Explanation: It is possible to make total tastiness 20in following way:- Do not buy first fruit, so that total price =0 and total tastiness =0.- Buy second fruit with coupon, so that total price =0+7 and total tastiness =0+8.- Buy third fruit with coupon, so that total price =7+3 and total tastiness =8+20.It can be proven that 28is the maximum total tastiness that can be obtained.
The key idea is to use dynamic programming to track the maximum tastiness achievable for each possible amount spent and number of coupons used. For each fruit, we consider three choices: skip, buy at full price, or buy with a coupon (if coupons remain). We update our DP table accordingly, ensuring we never exceed the budget or coupon limit.
classSolution:
defmaxTastiness(self, price: list[int], tastiness: list[int], maxAmount: int, maxCoupons: int) -> int:
n = len(price)
dp = [[0] * (maxCoupons +1) for _ in range(maxAmount +1)]
for i in range(n):
ndp = [row[:] for row in dp]
for amt in range(maxAmount +1):
for cpn in range(maxCoupons +1):
p = price[i]
if amt + p <= maxAmount:
ndp[amt + p][cpn] = max(ndp[amt + p][cpn], dp[amt][cpn] + tastiness[i])
if cpn +1<= maxCoupons:
cp = p //2if amt + cp <= maxAmount:
ndp[amt + cp][cpn +1] = max(ndp[amt + cp][cpn +1], dp[amt][cpn] + tastiness[i])
dp = ndp
ans =0for amt in range(maxAmount +1):
for cpn in range(maxCoupons +1):
ans = max(ans, dp[amt][cpn])
return ans
impl Solution {
pubfnmax_tastiness(price: Vec<i32>, tastiness: Vec<i32>, max_amount: i32, max_coupons: i32) -> i32 {
let n = price.len();
let ma = max_amount asusize;
let mc = max_coupons asusize;
letmut dp =vec![vec![0; mc +1]; ma +1];
for i in0..n {
letmut ndp = dp.clone();
for amt in0..=ma {
for cpn in0..=mc {
let p = price[i] asusize;
if amt + p <= ma {
ndp[amt + p][cpn] = ndp[amt + p][cpn].max(dp[amt][cpn] + tastiness[i]);
}
if cpn +1<= mc {
let cp = (price[i] /2) asusize;
if amt + cp <= ma {
ndp[amt + cp][cpn +1] = ndp[amt + cp][cpn +1].max(dp[amt][cpn] + tastiness[i]);
}
}
}
}
dp = ndp;
}
letmut ans =0;
for amt in0..=ma {
for cpn in0..=mc {
ans = ans.max(dp[amt][cpn]);
}
}
ans
}
}