(待完整) 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& group, vector& profit) { int K = group.size(), MOD = 1e9 + 7; //dp[k][g][p]使用计划[1,2,3,... k],最多g个人,盈利不少于p个方案个数 vector > > dp(K + 1, vector >(G + 1, vector(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]; } }; ```