哎, dp dp dp 太难了 分析的过程也给弄丢了
现写
dp状态表示 f[i][j][k] 表示只考虑前i个工作,选i个人,产生利润至少为k的方法个数
属性: num
状态计算
因为限制因素是选了第i个工作人够不够用,所以说当j >= group[i]的时候
f[i][j][k] = f[i - 1][j - group[i][max(0, k - profit[i]]
这里max就比较讲究了,因为我们表示的是 至少为k, 大于k当然也可以啦
当j < group[i] 的时候, f[i][j][k] = f[i - 1][j][k]
初始化f[0][0][0] = 1
class Solution {
public:
int profitableSchemes(int n, int minProfit, vector<int>& group, vector<int>& profit) {
int len = group.size(), MOD = (int)1e9 + 7;
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 members = group[i - 1], earn = profit[i - 1];
for (int j = 0; j <= n; j++) {
for (int k = 0; k <= minProfit; k++) {
if (j < members) {
dp[i][j][k] = dp[i - 1][j][k];
} else {
dp[i][j][k] = (dp[i - 1][j][k] + dp[i - 1][j - members][max(0, k - earn)]) % MOD;
}
}
}
}
int sum = 0;
for (int j = 0; j <= n; j++) {
sum = (sum + dp[len][j][minProfit]) % MOD;
}
return sum;
}
};
我们可以看出 f[i][][] 由 f[i - 1][][], 因此我们可以用二维数组来优化
f[j][k]
当 k = 0时, 无论多少人我们都能有一种方案 f[i][0] = 0
class Solution {
public:
int profitableSchemes(int n, int minProfit, vector<int>& group, vector<int>& profit) {
int len = group.size(), MOD = (int)1e9 + 7;
vector<vector<int>> f(n + 1, vector<int>(minProfit + 1));
for (int i = 0; i <= n; i++)
f[i][0] = 1;
for (int i = 0; i < len; i++)
{
int num = group[i], pro = profit[i];
for (int j = n; j >= num; j--)
{
for (int k = minProfit; k >= 0; k--)
f[j][k] =(f[j][k] + f[j - num][max(0, k - pro)]) %MOD;
}
}
return f[n][minProfit];
}
};