集团里有 n
名员工,他们可以完成各种各样的工作创造利润。
第 i
种工作会产生 profit[i]
的利润,它要求 group[i]
名成员共同参与。如果成员参与了其中一项工作,就不能参与另一项工作。
工作的任何至少产生 minProfit
利润的子集称为 盈利计划 。并且工作的成员总数最多为 n
。
有多少种计划可以选择?因为答案很大,所以 返回结果模 10^9 + 7
的值。
示例 1:
输入:n = 5, minProfit = 3, group = [2,2], profit = [2,3] 输出:2 解释:至少产生 3 的利润,该集团可以完成工作 0 和工作 1 ,或仅完成工作 1 。 总的来说,有两种计划。
示例 2:
输入:n = 10, minProfit = 5, group = [2,3,5], profit = [6,7,8] 输出:7 解释:至少产生 5 的利润,只要完成其中一种工作就行,所以该集团可以完成任何工作。 有 7 种可能的计划:(0),(1),(2),(0,1),(0,2),(1,2),以及 (0,1,2) 。
提示:
1 <= n <= 100
0 <= minProfit <= 100
1 <= group.length <= 100
1 <= group[i] <= 100
profit.length == group.length
0 <= profit[i] <= 100
方法一:动态规划
我们定义
对于第
最终的答案即为
时间复杂度
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]
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];
}
};
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]
}
func max(a, b int) int {
if a > b {
return a
}
return b
}