Replies: 3 comments
-
|
dp[i番目まで見る][区間始まりが何回あったか][現在の表裏]を持ちながらDP |
Beta Was this translation helpful? Give feedback.
-
|
あまり言及されていないDPで解いたので書きます。 DPの定義カードを裏返すのではなく、i番目に この値を DPの遷移Aの遷移Aは一枚ずつ置くので Bの遷移Bは区間で置くので、 普通に この中の 残った
また、 Python(159ms) import sys
input = lambda: sys.stdin.readline().rstrip("\r\n")
INF = 1<<60
N, K = map(int, input().split())
A = []
B = []
for _ in range(N):
a, b = map(int, input().split())
A.append(a)
B.append(b)
cum = [0]
for b in B: cum.append(cum[-1]+b)
dp = [-INF]*(K+1)
MX = [-INF]*(K+1)
MX[0] = 0
dp[0] = 0
for i in range(N):
ndp = [-INF]*(K+1)
for k in range(K+1):
# A
ndp[k] = max(ndp[k], dp[k]+A[i])
if k == K: continue
# B
ndp[k+1] = max(ndp[k+1], cum[i+1]+MX[k])
dp = ndp[:]
for k in range(K+1):
MX[k] = max(MX[k], dp[k]-cum[i+1])
print(max(dp)) |
Beta Was this translation helpful? Give feedback.
-
|
Kadane のアルゴリズムによる解法です。 前からみた累積和最大値を保存した配列を P(Prefix) とします。 Kadane のアルゴリズムによって、P のプレフィクスとある配列 X とのサフィックスを比較して最大値を更新する処理を、以下「マージ」とします。 すべてが表の状態は、初期状態に対して A をマージした状態です。 この裏返し処理を K 回行ったあとの P の末尾が答えとなります。 n,k = list(map(int, input().split(' ')))
AB = [list(map(int, input().split(' '))) for i in range(n)]
a,b = zip(*AB)
p = [-10**18] * (n+1)
def merge(x):
for i in range(n):
p[i+1] = max(p[i+1],max(0,p[i])+x[i])
merge(a)
for _ in range(k):
merge(b)
merge(a)
print(p[n]) |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
問題の感想や気づきを投稿・共有するスペースです
Beta Was this translation helpful? Give feedback.
All reactions