40 lines
2.3 KiB
Markdown
40 lines
2.3 KiB
Markdown
|
||
(待完整)
|
||
https://www.cnblogs.com/grandyang/p/11108205.html
|
||
|
||
* 如果g >= group[k - 1],则说明犯罪k可以执行,因为人数已经足够了
|
||
* 如果profit[k - 1] >= p,则说明只执行犯罪k就能达到利润p,可以单独执行,接着我们考虑必须执行犯罪k,然后加上前面的利润不低于p - profit[k - 1]的方案,这样凑出的方案利润也会超过p
|
||
* 否则犯罪k不能执行,此时只能直接将前面 dp[k - 1][g][p]利润超过p的方案搬过来
|
||
|
||
```
|
||
class Solution {
|
||
public:
|
||
int profitableSchemes(int G, int P, vector<int>& group, vector<int>& profit) {
|
||
int K = group.size(), MOD = 1e9 + 7;
|
||
//dp[k][g][p]使用计划[1,2,3,... k],最多g个人,盈利不少于p个方案个数
|
||
vector<vector<vector<int> > > dp(K + 1, vector<vector<int> >(G + 1, vector<int>(P + 1, 0)));
|
||
for (int k = 1; k <= K; ++k){
|
||
for (int g = 1; g <= G; ++g){
|
||
for (int p = 0; p <= P; ++p){
|
||
//如果人数g能够执行第k种犯罪(人数g >= 第k种犯罪需要的人数group[k - 1])
|
||
if (g >= group[k - 1]){
|
||
if (profit[k - 1] >= p){
|
||
//如果执行第k种犯罪获得的利润profit[k - 1]不小于p,则可以单独执行该犯罪
|
||
dp[k][g][p] += 1;
|
||
}
|
||
//将第k个方案产生的利润profit[k]与之前方案产生的利润凑出不少于p
|
||
//dp[k - 1][g - group[k]][p > profit[k] ? p - profit[k] : 0]表示在使用[1, k - 1]这些犯罪,使用人数不超过g - group[k],获得路润不少于p - profit[k]
|
||
//这样前面的产生p - profit[k]的利润再加上执行第k个犯罪的利润profit[k]就能到达到利润不少于p(注意p 可能大于 profit[k],所以不能为负数)
|
||
dp[k][g][p] = (dp[k][g][p] + dp[k - 1][g - group[k - 1]][p > profit[k - 1] ? p - profit[k - 1] : 0]) % MOD;
|
||
}
|
||
//不执行第k个犯罪,直接将前面的利润超过p的方案搬过来
|
||
dp[k][g][p] = (dp[k][g][p] + dp[k - 1][g][p]) % MOD;
|
||
}
|
||
}
|
||
}
|
||
return dp[K][G][P];
|
||
}
|
||
};
|
||
|
||
```
|