⭐️⭐️⭐️
# 題目敘述
There is a group of n
members, and a list of various crimes they could commit. The ith
crime generates a profit[i]
and requires group[i]
members to participate in it. If a member participates in one crime, that member can’t participate in another crime.
Let’s call a profitable scheme any subset of these crimes that generates at least minProfit
profit, and the total number of members participating in that subset of crimes is at most n
.
Return the number of schemes that can be chosen. Since the answer may be very large, return it modulo 10^9 + 7
.
# Example 1:
Input: n = 5, minProfit = 3, group = [2,2], profit = [2,3]
Output: 2
Explanation: To make a profit of at least 3, the group could either commit crimes 0 and 1, or just crime 1.
In total, there are 2 schemes.
# Example 2:
Input: n = 10, minProfit = 5, group = [2,3,5], profit = [6,7,8]
Output: 7
Explanation: To make a profit of at least 5, the group could commit any crimes, as long as they commit one.
There are 7 possible schemes: (0), (1), (2), (0,1), (0,2), (1,2), and (0,1,2).
# 解題思路
We define dp[i][j]
as the number of profitable schemes that can be formed with a minimum profit of i
and a total group size of j
. We can then update the dp array for each group by considering whether or not to include that group in each possible profitable scheme. The final answer is the sum of dp[minProfit][j]
for all j
from 0
to the group size limit.
# Solution
class Solution { | |
public: | |
int profitableSchemes(int n, int minProfit, vector<int>& group, vector<int>& profit) { | |
int mod = 1e9 + 7; | |
vector<vector<int>> dp(minProfit + 1, vector<int>(n + 1)); | |
dp[0][0] = 1; | |
for (int k=0; k<group.size(); k++) { | |
int g = group[k], p = profit[k]; | |
for (int i=minProfit; i>=0; i--) { | |
for (int j=n-g; j>=0; j--) { | |
int newProfit = min(minProfit, p + i); | |
dp[newProfit][j + g] += dp[i][j]; | |
dp[newProfit][j + g] %= mod; | |
} | |
} | |
} | |
int res = 0; | |
for (int i=0; i<=n; i++) { | |
res += dp[minProfit][i]; | |
res %= mod; | |
} | |
return res; | |
} | |
}; |
class Solution: | |
def profitableSchemes(self, n: int, minProfit: int, group: List[int], profit: List[int]) -> int: | |
mod = 10**9 + 7 | |
dp = [[0] * (n + 1) for _ in range(minProfit + 1)] | |
dp[0][0] = 1 | |
for g, p in zip(group, profit): | |
for i in range(minProfit, -1, -1): | |
for j in range(n-g, -1, -1): | |
dp[min(minProfit, p + i)][j + g] += dp[i][j] | |
dp[min(minProfit, p + i)][j + g] %= mod | |
return sum(dp[minProfit]) % mod |