题意:
集团里有 n 名员工,他们可以完成各种各样的工作创造利润。
第 i 种工作会产生 profit[i] 的利润,它要求 group[i] 名成员共同参与。
如果成员参与了其中一项工作,就不能参与另一项工作。
工作的任何至少产生 minProfit 利润的子集称为 盈利计划 。
并且工作的成员总数最多为 n 。
有多少种计划可以选择?因为答案很大,所以 返回结果模 10^9 + 7 的值。
1 <= n <= 100
0 <= minProfit <= 100
1 <= group.length <= 100
1 <= group[i] <= 100
profit.length == group.length
0 <= profit[i] <= 100
解法:
令d[i][j][k]表示前i种工作,一共用了j个人,收益为k的方案数,
注意当收益>=minProfit时是等价的,因此当收益>=minProfit时,令其=minProfit即可.
转移方程:
设当前工作需要x个人,收益为y,
1.如果不做当前工作,则d[i+1][j][k]+=d[i][j][k]
2.如果做当前工作,且j+x<=n,则d[i+1][j+x][min(k+y,mi)]+=d[i][j][k];
code:
const int mod=1e9+7;
int d[111][111][111];
class Solution {
public:
int profitableSchemes(int n, int mi, vector<int>& a, vector<int>& b) {
int p=a.size();
memset(d,0,sizeof d);
d[0][0][0]=1;
for(int i=0;i<p;i++){
for(int j=0;j<=n;j++){
for(int k=0;k<=mi;k++){
if(!d[i][j][k])continue;
d[i+1][j][k]=(d[i+1][j][k]+d[i][j][k])%mod;
int j1=j+a[i],k1=min(k+b[i],mi);
if(j1<=n){
d[i+1][j1][k1]=(d[i+1][j1][k1]+d[i][j][k])%mod;
}
}
}
}
int ans=0;
for(int j=0;j<=n;j++){
ans=(ans+d[p][j][mi])%mod;
}
return ans;
}
};