# format input
arr = list(input().split(','))
M = int(arr[0])
n = int(arr[1])
weight = list(map(int, arr[2].split()))
value = list(map(int, arr[3].split()))
# base case
dp = [[0] * (M + 1) for _ in range(n + 1)]
# 定义 dp[i][j] 代表前i个物品 数量为j 可得的最大价值
# 遍历状态
for i in range(1, n + 1):
    for j in range(1, M + 1):
        if j - weight[i - 1] < 0:
            dp[i][j] = dp[i - 1][j]
        else:
            dp[i][j] = max(dp[i - 1][j ], \
                           value[i - 1] + dp[i - 1][j - weight[i - 1]])

print(dp[n][M])  
用二维dp数组定义如下状态:
dp [i][j]
从前 i 个资产中选择,且条数不超过 j 时可获得的最大价值
base case : i = 0 or j =0->dp = 0
因为当可选的资产数为0 或者条数限制为0时,可获得的价值也为0

循环填充 dp table:
【Example】:
输入:10,10,4 9 10 3 4 10 8 9 5 10,7902 5742 5587 9719 5251 8964 6582 4498  2023
即有10 个资产
weight 4
9 10 3 4 10 8 9 5 10
value 7902         
5742
5587
9719
5251
8964
6582
4498
7669
2023




循环的过程其实是枚举dp状态,对于每个状态:
    如果包里还可以容纳第i个物品:
            更新dp = 选择最大(不添加第i个物品的价值, 添加第i个物品的价值)
    否则:
            更新dp = 不添加第i个物品的价值  # 因为放不下