879. Profitable Schemes(背包计数)

https://leetcode.com/problems/profitable-schemes/

题意:有G个人,有n种犯罪方式每种犯罪方式都可以获得profit[i]的利益,每种犯罪方式都需要group[i]个人,要使获得利益大于等于P,求有多少种方式。

思路:G个人等价于背包的容量限制。设dp[i][j][k]表示前i种犯罪方式,使用j个人,获得k的利益的方案数。由于第i种犯罪方式只和第i-1种有关,所以可以滚动成2维dp,dp[j][k]即可,不过需要注意的是j,k需要逆推。

dp[j][k]+=dp[j-group[i]] [k-profit[i]];

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+7;
typedef long long ll;
class Solution {
public:
    int profitableSchemes(int G, int P, vector<int>& group, vector<int>& profit) {
        int dp[105][10005];
        memset(dp,0,sizeof(dp));
        int n = profit.size();
        int mod = 1e9+7;
        int tot=0;
        for(auto &t:profit){
          tot+=t;
        }
        dp[0][0]=1;
        for(int i=0;i<n;i++){
          for(int j=G;j>=group[i];j--){
            for(int k=tot;k>=profit[i];k--){
              dp[j][k]+=dp[j-group[i]][k-profit[i]];
              dp[j][k]%=mod;
            }
          }
        }
        int ans=0;
        for(int k=P;k<=tot;k++){
          for(int i=1;i<=G;i++){
            ans=(ans+dp[i][k])%mod;
          }
        }
        return ans;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_40774175/article/details/89075815
今日推荐