以单行dp表示1 - V 容量的背包,dp[j]表示当前循环装满j容量的背包的最大价值。不断通过转移方程在循环中更新列表,最终列表中的最大的值是问题1答案,最后一个值是问题2答案。

while True:
    try:
        n, V = map(int, input().split())
        v, w = [], []
        for i in range(n):
            l = list(map(int, input().split()))
            v.append(l[0])  # 物品重量列表
            w.append(l[1])  # 物品价值列表
        dp = [0 for i in range(V + 1)]  # dp[j] 表示当前行 装满j容量的背包可以获得的最大价值
        for i in range(n):
            for j in range(V + 1):
                if v[i] <= V:  # 剔除不符合条件的值
                    # 条件1如果物品刚好可以放到j容量的背包中更新dp[j]的值,条件2当当前行物品重量与本行前已存在的物品重量组合成j的重量时更新dp[j]的值
                    if j - v[i] == 0 or (j - v[i] > 0 and dp[j - v[i]] > 0):
                        # 比较当前装满j重量背包的最大价值与 本行新累加的装满背包的新重量的较大值更新到dp[j]
                        dp[j] = max(dp[j], dp[j - v[i]] + w[i])
        print(max(dp))
        print(dp[V])
    except:
        break