AcWing 1019. 庆功会 多重背包模板题
原题链接
简单
作者:
皓首不倦
,
2020-07-24 13:23:00
,
所有人可见
,
阅读 599
'''
多重背包模板题
'''
from collections import deque
arr = []
N, V = map(int, input().split())
for _ in range(N):
v, w, s = map(int, input().split())
arr.append((v, w, s))
dp = [[0] * (V + 1) for _ in range(N)]
for i in range(N):
# 开销,价值,最大数量
ci, wi, si = arr[i]
if i == 0:
for j in range(V + 1):
cnt = min(j // ci, si)
dp[i][j] = cnt * wi
else:
for window_start in range(0, min(V, ci)):
dp[i][window_start] = dp[i - 1][window_start]
que = deque()
que.append((dp[i - 1][window_start], 0)) # [入队数值,入队时间戳]
time_cnt = 0
for j in range(window_start + ci, V + 1, ci):
time_cnt += 1
# 删除过期数据
while len(que) > 0 and time_cnt - que[0][1] >= si + 1:
que.popleft()
while len(que) > 0 and que[-1][0] + (time_cnt - que[-1][1]) * wi <= dp[i - 1][j]:
que.pop()
que.append((dp[i - 1][j], time_cnt))
dp[i][j] = que[0][0] + (time_cnt - que[0][1]) * wi
print(dp[N - 1][V])