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 modulo10^9 + 7.
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:
1
2
3
4
5
6
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).
Use dynamic programming to count the number of ways to select crimes such that the total number of members does not exceed n and the total profit is at least minProfit.
Use a DP table dp[i][j][k] where i is the number of crimes considered, j is the number of members used, and k is the profit achieved (capped at minProfit).
For each crime, update the DP table by considering both including and excluding the crime.
The answer is the sum of all dp[len][j][minProfit] for j in 0..n.
classSolution {
public:int profitableSchemes(int n, int minProfit, vector<int>& group, vector<int>& profit) {
int MOD =1e9+7, len = group.size();
vector<vector<vector<int>>> dp(len+1, vector<vector<int>>(n+1, vector<int>(minProfit+1)));
dp[0][0][0] =1;
for (int i =1; i <= len; ++i) {
int g = group[i-1], p = profit[i-1];
for (int j =0; j <= n; ++j) {
for (int k =0; k <= minProfit; ++k) {
dp[i][j][k] = dp[i-1][j][k];
if (j >= g) {
int newProfit = min(minProfit, k + p);
dp[i][j][newProfit] = (dp[i][j][newProfit] + dp[i-1][j-g][k]) % MOD;
}
}
}
}
int res =0;
for (int j =0; j <= n; ++j) res = (res + dp[len][j][minProfit]) % MOD;
return res;
}
};
classSolution {
publicintprofitableSchemes(int n, int minProfit, int[] group, int[] profit) {
int MOD = 1_000_000_007, len = group.length;
int[][][] dp =newint[len+1][n+1][minProfit+1];
dp[0][0][0]= 1;
for (int i = 1; i <= len; ++i) {
int g = group[i-1], p = profit[i-1];
for (int j = 0; j <= n; ++j) {
for (int k = 0; k <= minProfit; ++k) {
dp[i][j][k]= dp[i-1][j][k];
if (j >= g) {
int newProfit = Math.min(minProfit, k + p);
dp[i][j][newProfit]= (dp[i][j][newProfit]+ dp[i-1][j-g][k]) % MOD;
}
}
}
}
int res = 0;
for (int j = 0; j <= n; ++j) res = (res + dp[len][j][minProfit]) % MOD;
return res;
}
}
classSolution {
funprofitableSchemes(n: Int, minProfit: Int, group: IntArray, profit: IntArray): Int {
val MOD = 1_000_000_007
val len = group.size
val dp = Array(len+1) { Array(n+1) { IntArray(minProfit+1) } }
dp[0][0][0] = 1for (i in1..len) {
val g = group[i-1]; val p = profit[i-1]
for (j in0..n) {
for (k in0..minProfit) {
dp[i][j][k] = dp[i-1][j][k]
if (j >= g) {
val newProfit = minOf(minProfit, k + p)
dp[i][j][newProfit] = (dp[i][j][newProfit] + dp[i-1][j-g][k]) % MOD
}
}
}
}
var res = 0for (j in0..n) res = (res + dp[len][j][minProfit]) % MOD
return res
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
classSolution:
defprofitableSchemes(self, n: int, minProfit: int, group: list[int], profit: list[int]) -> int:
MOD =10**9+7 len_ = len(group)
dp = [[[0]*(minProfit+1) for _ in range(n+1)] for _ in range(len_+1)]
dp[0][0][0] =1for i in range(1, len_+1):
g, p = group[i-1], profit[i-1]
for j in range(n+1):
for k in range(minProfit+1):
dp[i][j][k] = dp[i-1][j][k]
if j >= g:
newProfit = min(minProfit, k + p)
dp[i][j][newProfit] = (dp[i][j][newProfit] + dp[i-1][j-g][k]) % MOD
return sum(dp[len_][j][minProfit] for j in range(n+1)) % MOD
impl Solution {
pubfnprofitable_schemes(n: i32, min_profit: i32, group: Vec<i32>, profit: Vec<i32>) -> i32 {
let n = n asusize;
let min_profit = min_profit asusize;
let len = group.len();
letmut dp =vec![vec![vec![0; min_profit+1]; n+1]; len+1];
dp[0][0][0] =1;
for i in1..=len {
let g = group[i-1] asusize;
let p = profit[i-1] asusize;
for j in0..=n {
for k in0..=min_profit {
dp[i][j][k] = dp[i-1][j][k];
if j >= g {
let new_profit = std::cmp::min(min_profit, k + p);
dp[i][j][new_profit] = (dp[i][j][new_profit] + dp[i-1][j-g][k]) %1_000_000_007;
}
}
}
}
letmut res =0;
for j in0..=n { res = (res + dp[len][j][min_profit]) %1_000_000_007; }
res
}
}