一、 题目
1. 题目描述
2. 原题链接
链接: 879. 盈利计划
二、 解题报告
1. 思路分析
非常明显的二维费用01背包。
工作可以看成,个数=1个,体积是group[i],价值是profit[i]。
体积上界是n*profit[i] = 10000,另外要枚举物品和体积。复杂度来到1e8,会TLE
- 需要优化,这里方法是定义f[i][j][k] 从前i个里选,盈利至少j(注意不是恰好j),员工选了k个的方案数。
- 则转移为f[j][k]=f[j][k]+f[max(0,j-p)][k-g];注意max(0,j-p)。
2. 复杂度分析
最坏时间复杂度O(1e6)
3. 代码实现
二维费用背包
。
MOD = 10**9+7
class Solution:
def profitableSchemes(self, n: int, minProfit: int, group: List[int], profit: List[int]) -> int:
# mx = sum(sorted(profit,reverse=True)[:n])
f = [[0]*(n+1) for _ in range(minProfit+1)] # f[i][j][k] 从前i个里选,盈利至少j,员工选了k个的方案数
f[0][0] = 1
for g,p in zip(group,profit):
if g>n:continue
for j in range(minProfit,-1,-1): # j的枚举下界是0
x = j-p if j-p >0 else 0 # 注意,由于这里定义的是盈利至少j,而不是恰好j,因此x=max(0,j-p);且j的枚举下界是0
for k in range(n,g-1,-1):
f[j][k]=(f[j][k]+f[x][k-g])%MOD
return sum(f[-1])%MOD
# TLE
# mx = sum(profit)
# f = [[0]*(n+1) for _ in range(mx+1)] # f[i][j][k] 从前i个里选,盈利j,员工选了k个的方案数
# f[0][0] = 1
# for g,p in zip(group,profit):
# for j in range(mx,p-1,-1):
# for k in range(n,g-1,-1):
# f[j][k]+=f[j-p][k-g]
# f[j][k]%=MOD
# return sum(sum(v)%MOD for v in f[minProfit:])%MOD
三、 本题小结
- 还不太理解,但是先抄了。有点像前缀和+背包