题目描述:
帮派里有 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<int>& group, vector<int>& profit) {
const long Mod = 1e9 + 7;
int T = group.size();
vector<vector<vector<int>>> dp(T+1,vector<vector<int>>(P+1,vector<int>(G+1,0)))