白駿7579アプリケーション


質問する


https://www.acmicpc.net/problem/7579

コード#コード#

input = __import__('sys').stdin.readline
n, m = map(int, input().split())
mlist = list(map(int, input().split()))
clist = list(map(int, input().split()))
sum_cost = sum(clist)+1
dp = [[0]*sum_cost for _ in range(n+1)]

for i in range(1, n+1):
    for j in range(sum_cost):
        if clist[i-1] > j:
            dp[i][j] = dp[i-1][j]
        else:
            dp[i][j] = max(mlist[i-1]+dp[i-1][j-clist[i-1]], dp[i-1][j])

for i in range(sum_cost):
    if dp[-1][i] >= m:
        print(i)
        break

に答える


リュックサックの問題は典型的なDPタイプの一つです.
問題は、所定のメモリを得るために最小のコストを出力する必要があります.このコストを得るために最大のメモリを見つけることができれば、リュックサックの問題と同じ解法を使用して問題を解決することができます.
問題のテストケースを例にdpテーブルを作成します.

ここで、青色領域はdpテーブルであり、dp[i][j]は、jと同じコストと1からiインデックスのメモリを使用できる場合に得られる最大メモリ値を示す.
点火式.
if clist[i-1] > j:
     dp[i][j] = dp[i-1][j]
else:
     dp[i][j] = max(mlist[i-1]+dp[i-1][j-clist[i-1]], dp[i-1][j])
このように出てきたのです
dpの下線の周囲には、まずm以上のi値が印刷される.