假设有一个与G人的团伙,以及他们可能犯下的各种罪行。第i次犯罪会产生利润值利润[i],并要求团伙[i]帮派成员参与。
如果帮派成员参与一项犯罪,则他不能参与另一项犯罪。现在,让我们定义有利可图的方案,这些犯罪的任何子集至少产生P利润,并且参与该犯罪子集的成员总数最多为G。
我们必须找出可以选择多少个方案?答案可能非常大,因此以10 ^ 9 + 7为模返回。
因此,如果输入像G = 5,P = 3并且组= [2,2],利润= [2,3],那么输出将为2
为了解决这个问题,我们将遵循以下步骤-
ret:= 0
定义一个尺寸为(G + 1)x(P + 1)的2D数组dp
dp [0,0]:= 1
对于初始化k:= 0,当k <组大小时,更新(将k增加1),-
对于初始化j:= P,当j> = 0时,更新(将j减1),执行-
dp [i + g,P和j + p的最小值]
dp [i + g,P和j + p的最小值]
p:=利润[k],g:=小组[k]
对于初始化i:= G-g,当i> = 0时,更新(将i减1),-
对于初始化i:= 0,当i <= G时,更新(将i增加1),执行-
ret:= ret + dp [i,P]
ret:= ret mod m
返回ret
让我们看下面的实现以更好地理解-
#include <bits/stdc++.h> using namespace std; const int m = 1e9 + 7; class Solution { public: int profitableSchemes(int G, int P, vector<int> &group, vector<int> &lprofit) { int ret = 0; vector<vector<int>> dp(G + 1, vector<int>(P + 1)); dp[0][0] = 1; for (int k = 0; k < group.size(); k++) { int p = profit[k]; int g = group[k]; for (int i = G - g; i >= 0; i--) { for (int j = P; j >= 0; j--) { dp[i + g][min(P, j + p)] += dp[i][j]; dp[i + g][min(P, j + p)] %= m; } } } for (int i = 0; i <= G; i++) { ret += dp[i][P]; ret %= m; } return ret; } }; main(){ Solution ob; vector<int> v = {2,2}, v1 = {2,3}; cout << (ob.profitableSchemes(5,3,v, v1)); }
5, 3, [2,2], [2,3]
输出结果
2