Skip to main content
  1. Posts/

LeetCode-879 盈利计划

·1 min·

LeetCode-879 盈利计划 #

Solution 1 #

枚举所有可能的情况. 记 $dp[i][j][k]$ 为有 $i$ 个员工, 可选任务从 $j$ 开始, 还需盈利 $k$ 的方案数. 状态转移方程如下: $$ dp[i][j][k] = \begin{cases} dp[i][j + 1][k], \ if\ group[j] > i\ dp[i - group[j]][j + 1][k - profit[j]],\ otherwise \end{cases} $$ 我们可以用记忆化搜索来替代递推过程. 代码如下:

#define ll long long
class Solution {
public:
    const int MOD = 1e9 + 7;
    int m;
    int dp[110][110][110];
    vector<int> _group, _profit;
    int f(int n, int i, int p) {
        if (i == m && p <= 0) {
            return 1;
        }
        if (i == m && p > 0) {
            return 0;
        }
        if (dp[n][i][p] != -1) {
            return dp[n][i][p];
        }
        dp[n][i][p] = 0;
        if (n - _group[i] >= 0) {
            int np = (p >= _profit[i])? p - _profit[i]: 0;
            dp[n][i][p] = f(n - _group[i], i + 1, np);
        }
        dp[n][i][p] = (dp[n][i][p] + f(n, i + 1, p)) % MOD;
        return dp[n][i][p];
    }

    int profitableSchemes(int n, int minProfit, vector<int>& group, vector<int>& profit) {
        for (int i = 0; i < 110; i++) {
            for (int j = 0; j < 110; j++) {
                for (int k = 0; k < 110; k++) {
                    dp[i][j][k] = -1;
                }
            }
        }
        m = group.size();
        _group = group;
        _profit = profit;
        return f(n, 0, minProfit);
    }
};