結果
| 問題 |
No.2026 Yet Another Knapsack Problem
|
| コンテスト | |
| ユーザー |
lam6er
|
| 提出日時 | 2025-03-31 17:53:19 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 2,794 bytes |
| コンパイル時間 | 180 ms |
| コンパイル使用メモリ | 82,472 KB |
| 実行使用メモリ | 87,108 KB |
| 最終ジャッジ日時 | 2025-03-31 17:55:29 |
| 合計ジャッジ時間 | 44,584 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 35 TLE * 1 -- * 6 |
ソースコード
import sys
def main():
input = sys.stdin.read().split()
ptr = 0
N = int(input[ptr])
ptr += 1
c1 = N
v1 = int(input[ptr+1])
ptr += 2 # first line is type 1
other_items = []
for i in range(2, N+1):
ci = int(input[ptr])
vi = int(input[ptr+1])
ptr +=2
other_items.append( (i, ci, vi) ) # i is the weight, ci is count, vi is value per item
# Precompute DP_other[j][m], j <=1250, m <=2500
max_j_other = N // 2 # since other items have weight >=2, j <= m//2 and m <=N. max_j is N//2 for N even
dp_other = [ [ -float('inf') ] * (N+1) for _ in range(max_j_other + 1) ]
dp_other[0][0] = 0
for (weight, cnt, val) in other_items:
# Decompose cnt into binary components
s = 1
components = []
remaining = cnt
while remaining > 0:
current = min(s, remaining)
components.append(current)
remaining -= current
s *= 2
for s_part in components:
# For each component, process 0-1
# We need to update dp_other, but in reverse order
for j in reversed(range(max_j_other + 1 - s_part)):
for m in reversed(range(N + 1 - s_part * weight)):
if dp_other[j][m] == -float('inf'):
continue
new_j = j + s_part
new_m = m + s_part * weight
if new_j > max_j_other or new_m > N:
continue
new_val = dp_other[j][m] + s_part * val
if new_val > dp_other[new_j][new_m]:
dp_other[new_j][new_m] = new_val
# Compute prefix max for each j
max_prefix = [ [ -float('inf') ] * (N+1) for _ in range(max_j_other +1) ]
for j in range(max_j_other + 1):
current_max = -float('inf')
for m in range(N+1):
if dp_other[j][m] > current_max:
current_max = dp_other[j][m]
max_prefix[j][m] = current_max
# Now compute each k's answer
for k in range(1, N+1):
max_val = -float('inf')
# j can be from 0 to min(k, max_j_other)
max_possible_j = min(k, max_j_other)
for j in range(0, max_possible_j +1):
s = k - j
if s <0:
continue
m_max_allowed = N - k + j
if m_max_allowed <0:
continue
m_max_allowed = min(m_max_allowed, N)
current_other = max_prefix[j][m_max_allowed]
if current_other == -float('inf'):
continue
total = current_other + s * v1
if total > max_val:
max_val = total
print(max_val)
if __name__ == "__main__":
main()
lam6er