結果
| 問題 |
No.2026 Yet Another Knapsack Problem
|
| コンテスト | |
| ユーザー |
gew1fw
|
| 提出日時 | 2025-06-12 20:31:37 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 2,482 bytes |
| コンパイル時間 | 177 ms |
| コンパイル使用メモリ | 82,288 KB |
| 実行使用メモリ | 88,824 KB |
| 最終ジャッジ日時 | 2025-06-12 20:33:27 |
| 合計ジャッジ時間 | 68,747 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| 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
c = []
v = []
for _ in range(N):
ci = int(input[ptr])
vi = int(input[ptr+1])
c.append(ci)
v.append(vi)
ptr += 2
# Initialize DP for other items (excluding the first item)
dp_other = [[-float('inf')] * (N + 1) for _ in range(N + 1)]
dp_other[0][0] = 0
# Process items from 2 to N (index 1 to N-1 in the list)
for i in range(1, N):
current_i = i + 1 # weight is i+1 as per problem statement
current_c = c[i]
current_v = v[i]
max_t = min(current_c, N // current_i)
if max_t == 0:
continue # cannot take any of this item
# Binary decomposition
s = 1
remaining = max_t
while remaining > 0:
take = min(s, remaining)
weight = take * current_i
value = take * current_v
# Update DP in reverse to avoid overwriting
for k in range(N, take - 1, -1):
for w in range(N, weight - 1, -1):
if dp_other[k - take][w - weight] != -float('inf'):
if dp_other[k][w] < dp_other[k - take][w - weight] + value:
dp_other[k][w] = dp_other[k - take][w - weight] + value
remaining -= take
s *= 2
# Preprocess max_val[k][w] which is the maximum value for k items with weight <= w
max_val = [[-float('inf')] * (N + 1) for _ in range(N + 1)]
for k in range(N + 1):
current_max = -float('inf')
for w in range(N + 1):
if dp_other[k][w] > current_max:
current_max = dp_other[k][w]
max_val[k][w] = current_max
# Process the first item (weight 1, count c[0] = N)
v1 = v[0]
ans = [-float('inf')] * (N + 1)
for k in range(1, N + 1):
max_total = -float('inf')
for k_prime in range(0, k + 1):
t = k - k_prime
w_max = N - t
if w_max < 0:
continue
w_max = min(w_max, N)
current_max = max_val[k_prime][w_max]
if current_max == -float('inf'):
continue
total = current_max + t * v1
if total > max_total:
max_total = total
ans[k] = max_total
for k in range(1, N + 1):
print(ans[k])
if __name__ == '__main__':
main()
gew1fw