zoukankan      html  css  js  c++  java
  • 879. 盈利计划 力扣 动态规划 难

    题目描述:

    集团里有 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 。
    总的来说,有两种计划。

    题解:

    由于我们定义的第二维是工作利润至少为 k 而不是 工作利润恰好为 k,因此上述状态转移方程中右侧的第二维是 max(0,k-profit[i]), 而不是 k - profit[i]。读者可以思考这一步的妙处所在。

    类似于0,1背包的写法,只是维度含义定义不同,不太能考虑到

    dp[i][j]:表示 i 个人,至少产生 j 利润的方法数。

    题源:https://leetcode-cn.com/problems/profitable-schemes/

    题解:https://leetcode-cn.com/problems/profitable-schemes/solution/cdong-tai-gui-hua-by-heroding-8q6w/

    class Solution {
    public:
        int profitableSchemes(int n, int minProfit, vector<int>& group, vector<int>& profit) {
            int l=profit.size();
            int dp[105][105];
    
            int mod=(int)1e9+7;
            memset(dp,0,sizeof(dp));
            for(int i=0;i<=n;i++) dp[i][0]=1;  //这一步决定了,最后的结果需不需要重新累加
    
            for(int i=0;i<l;i++)
              for (int ren=n;ren>=group[i];ren--)
                for (int pro=minProfit;pro>=0;pro--)
                    dp[ren][pro]=( dp[ren][pro] + dp[ren-group[i]][max(0,pro-profit[i])] ) % mod;   
        
           return dp[n][minProfit];
        }
    };
  • 相关阅读:
    Service Location Protocol SLP
    [http 1.1] M-POST
    安装 wbemcli
    [http 1.1] M-POST w3
    [CODEVS 1288]埃及分数
    [NOIp 2013]货车运输
    [测试题]gentree
    [USACO 07NOV]Cow Relays
    [USACO 13DEC]Vacation Planning(gold)
    [CODEVS 2495]水叮当的舞步
  • 原文地址:https://www.cnblogs.com/stepping/p/14882489.html
Copyright © 2011-2022 走看看