Leetcode 879. Profitable Schemes

There is a group of n members, and a list of various crimes they could commit. The ith crime generates a profit[i] and requires group[i] members to participate in it. If a member participates in one crime, that member can't participate in another crime.

Let's call a profitable scheme any subset of these crimes that generates at least minProfit profit, and the total number of members participating in that subset of crimes is at most n.

Return the number of schemes that can be chosen. Since the answer may be very large, return it modulo 10^9 + 7.

思路:

第i次行动需要消耗人力group[i],并且获得利润profit[i],在总人力不超过n的情况下,有多少个行动组合满足利润不小于minProfit

熟悉的取模10^9 +7,大概率就是动态规划了

需要一个二维数组dp去记录之前i-1时 人力g、利润p对应的行动组合个数

当计算第i次行动时,当前的组合个数等于 g- group[i], p - profit[i]时的组合个数

因此得出状态转移方程:

 dp[g][p] += dp[g-group[i]][p- profit[i]];

注意的问题:

  1. 初始值,dp[0][0]为1
  2. dp中人力和利润纬度都需要从大往小计算,从小往大会重复计算
  3. 大于当利润大等于minProfit时,总次数就记录在dp[g][ minProfit]中
  4. 当minProfit==0时,空集也是一个答案

代码

int profitableSchemes(int n, int minProfit, vector<int>& group, vector<int>& profit) {
        vector<vector<int> > dp(101, vector<int>(101,0));
        int md = (1e9)+7, sm = (minProfit ==0);
        dp[0][0] = 1;
        for (int i = 0; i< group.size(); i ++) {
            for (int j = n; j >= group[i]; j --) {
                for (int k = minProfit; k >= 0; k --) {
                    if (k + profit[i] >= minProfit) {
                        (sm += dp[j- group[i]][k])%=md;
                        (dp[j][minProfit] += dp[j- group[i]][k]) %=md;
                    }
                    else {
                        (dp[j][k + profit[i]] += dp[j-group[i]][k]) %=md;
                    }
                }
            }
        }
        return sm;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值