leetcode-master/problems/0879.盈利计划.md

2.3 KiB
Raw Blame History

(待完整) 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];
    }
};