Welcome to Subscribe On Youtube
879. Profitable Schemes
Description
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 109 + 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).
Constraints:
1 <= n <= 100
0 <= minProfit <= 100
1 <= group.length <= 100
1 <= group[i] <= 100
profit.length == group.length
0 <= profit[i] <= 100
Solutions
Solution 1: recursion with memoization
We design a function
The execution process of function
- If
, it means that all the jobs have been considered. Ifi=n , the number of schemes isk≥minProfit , otherwise the number of schemes is1 ;0 - If
, we can choose not to choose thei<n -th job, then the number of schemes isi ; ifdfs(i+1,j,k) , we can also choose thej+group[i]≤n -th job, then the number of schemes isi . Here we limit the profit upper limit todfs(i+1,j+group[i],min(k+profit[i],minProfit)) , because the profit exceedingminProfit has no effect on our answer.minProfit
Finally, return
In order to avoid repeated calculation, we can use the method of memoization. We use a three-dimensional array
The time complexity is
Solution 2: Dynamic Programming
We define
For the
The final answer is
The time complexity is
-
class Solution { public int profitableSchemes(int n, int minProfit, int[] group, int[] profit) { final int mod = (int) 1e9 + 7; int m = group.length; int[][][] f = new int[m + 1][n + 1][minProfit + 1]; for (int j = 0; j <= n; ++j) { f[0][j][0] = 1; } for (int i = 1; i <= m; ++i) { for (int j = 0; j <= n; ++j) { for (int k = 0; k <= minProfit; ++k) { f[i][j][k] = f[i - 1][j][k]; if (j >= group[i - 1]) { f[i][j][k] = (f[i][j][k] + f[i - 1][j - group[i - 1]][Math.max(0, k - profit[i - 1])]) % mod; } } } } return f[m][n][minProfit]; } }
-
class Solution { public: int profitableSchemes(int n, int minProfit, vector<int>& group, vector<int>& profit) { int m = group.size(); int f[m + 1][n + 1][minProfit + 1]; memset(f, 0, sizeof(f)); for (int j = 0; j <= n; ++j) { f[0][j][0] = 1; } const int mod = 1e9 + 7; for (int i = 1; i <= m; ++i) { for (int j = 0; j <= n; ++j) { for (int k = 0; k <= minProfit; ++k) { f[i][j][k] = f[i - 1][j][k]; if (j >= group[i - 1]) { f[i][j][k] = (f[i][j][k] + f[i - 1][j - group[i - 1]][max(0, k - profit[i - 1])]) % mod; } } } } return f[m][n][minProfit]; } };
-
class Solution: def profitableSchemes( self, n: int, minProfit: int, group: List[int], profit: List[int] ) -> int: mod = 10**9 + 7 m = len(group) f = [[[0] * (minProfit + 1) for _ in range(n + 1)] for _ in range(m + 1)] for j in range(n + 1): f[0][j][0] = 1 for i, (x, p) in enumerate(zip(group, profit), 1): for j in range(n + 1): for k in range(minProfit + 1): f[i][j][k] = f[i - 1][j][k] if j >= x: f[i][j][k] = (f[i][j][k] + f[i - 1][j - x][max(0, k - p)]) % mod return f[m][n][minProfit]
-
func profitableSchemes(n int, minProfit int, group []int, profit []int) int { m := len(group) f := make([][][]int, m+1) for i := range f { f[i] = make([][]int, n+1) for j := range f[i] { f[i][j] = make([]int, minProfit+1) } } for j := 0; j <= n; j++ { f[0][j][0] = 1 } const mod = 1e9 + 7 for i := 1; i <= m; i++ { for j := 0; j <= n; j++ { for k := 0; k <= minProfit; k++ { f[i][j][k] = f[i-1][j][k] if j >= group[i-1] { f[i][j][k] += f[i-1][j-group[i-1]][max(0, k-profit[i-1])] f[i][j][k] %= mod } } } } return f[m][n][minProfit] }