其他分享
首页 > 其他分享> > L879. 盈利计划

L879. 盈利计划

作者:互联网

集团里有 n 名员工,他们可以完成各种各样的工作创造利润。

第 i 种工作会产生 profit[i] 的利润,它要求 group[i] 名成员共同参与。如果成员参与了其中一项工作,就不能参与另一项工作。

工作的任何至少产生 minProfit 利润的子集称为盈利计划。并且工作的成员总数最多为 n 。

有多少种计划可以选择?因为答案很大,所以 返回结果模 10^9 + 7 的值。

示例 1:

输入:n = 5, minProfit = 3, group = [2,2], profit = [2,3]
输出:2
解释:至少产生 3 的利润,该集团可以完成工作 0 和工作 1 ,或仅完成工作 1 。
总的来说,有两种计划。
示例 2:

输入:n = 10, minProfit = 5, group = [2,3,5], profit = [6,7,8]
输出:7
解释:至少产生 5 的利润,只要完成其中一种工作就行,所以该集团可以完成任何工作。
有 7 种可能的计划:(0),(1),(2),(0,1),(0,2),(1,2),以及 (0,1,2) 。

提示:

1 <= n <= 100
0 <= minProfit <= 100
1 <= group.length <= 100
1 <= group[i] <= 100
profit.length == group.length
0 <= profit[i] <= 100

在这里插入图片描述
关键是要能列出dp,找到转换关系
另外,模运算(%)是个耗时的元算,不过这个问题里边每次都是两个小于MOD的数相加之后再对MOD取模,这就等价于相加之后如果比MOD大,然后减一个MOD就行
通过实践发现,使用%远比-省时间
dp[j][k]的含义为当前i序号的犯罪,在j名罪犯的行动下,获取k的利益。
那么dp[j][0]=1,因为如果不需要获取利益,罪犯人数符合条件都可以满足为方法。
此题需要注意的是空间压缩时,k>=0而不是k>=P,我们可以看到dp[j][k]+=dp[j-g][k-max(k-p,0)],这是因为在剩余所需的利益k小于当前罪行带来的p时,坐标可能小于0,但是这种情况依然是满足条件的,比如总利益为5,单个罪行利益为6,我们依旧需要把它们算上。

class Solution {

    public int profitableSchemes(int n, int minProfit, int[] group, int[] profit) {
        int mod = 1_000_000_000 + 7;
        int len = group.length;

        int[][] dp = new int[n + 1][minProfit + 1];
        //选取两个维度,用工人数,当前受益,题目是满足最小受益的总和数,必然要累加
        //这里与通用思路不同,不是一一列举超出最大收益的情况有多少,最后累加,而是
        //minProfit从0-minProfit依次递推出

        //初始化
        dp[0][0] = 1;//一般都会初始化,可参照

        for(int i = 0; i<= n; i++){
            dp[i][0] = 1;
        }

        for(int i = 0; i < len; i++){
            int g = group[i];//对于i活动,所需要的人数,n为总人数,相当于指定了一个下界
            int p = profit[i];//对于i活动,所得的盈利,作为最后一维

            //这里是一个难点,如何与g.p产生联系
            for(int j = n; j >= g; j--){//这里满足了人数的限制
                //倒序
                for(int k = minProfit; k >= 0; k--){
                    dp[j][k] += dp[j - g][Math.max((k - p), 0)];
                    //有可能k - p<0,即当前受益太大,直接参照上次受益为0的即可
                    //实际dp[x][0]并没有意义,需要事先设定;这是最特殊的地方
                    if(dp[j][k] > mod) dp[j][k] %= mod;
                }
            }
        }
        return dp[n][minProfit];
    }
}

标签:盈利,group,int,profit,minProfit,L879,计划,dp,MOD
来源: https://blog.csdn.net/weixin_41759020/article/details/116302110