Leetcode 879 盈利计划 (动态规划解法 c++)

题目描述:

帮派里有 G 名成员,他们可能犯下各种各样的罪行。第 i 种犯罪会产生 profit[i] 的利润,它要求 group[i] 名成员共同参与。让我们把这些犯罪的任何子集称为盈利计划,该计划至少产生 P 的利润。有多少种方案可以选择?因为答案很大,所以返回它模 10^9 + 7 的值。

设dp[i][j][k]的含义为前i个犯罪花费k个人达到至少j利润的方案数,则有选做第i个犯罪还是不选:

dp[i][j][k] = dp[i-1][j][k] + dp[i-1][j-profit[i-1]][k-group[i-1]]

含义是不做第i个犯罪,那么有dp[i-1][j][k]个方案;做第i个犯罪,有dp[i-1][j-profit[i-1]][k-group[i-1]]个方案。注意group和profit都是从下标0开始,所以为i-1。

动态规划很重要的一点是边界问题。当利润为0时,无论i和k为多少,dp[i][0][k]=1,表示只有一种方案(就是不做)。

代码:

class Solution {
public:
    int profitableSchemes(int G, int P, vector& group, vector& profit) {
        const long Mod = 1e9 + 7;
        int T = group.size();
        vector>> dp(T+1,vector>(P+1,vector(G+1,0)));
        // dp[0][0][0] = 1;
        for (int i = 0;i<=T;i++){
            for(int j = 0;j<=G;j++){
                dp[i][0][j] = 1;
            }
        }
        for (int t = 1;t<=T;++t){
            int p = profit[t-1];
            int g = group[t-1];
            for(int i = 0;i<=P;++i){
                for (int j = 0; j<=G;++j){
                    dp[t][i][j] = (dp[t-1][i][j] + (j

还有一些小细节需要注意,判断利润是否大于0,以及花费的人数是否大于第t个任务所需的人数。

你可能感兴趣的:(算法练习)