# 自下向上,先小问题再大问题,递推
N, C = map(int, input().split()) # 物品数量,背包体积
c = [0] # 每件物品的体积
w = [0] # 每件物品的价值
for i in range(N):
a, b = map(int, input().split())
c.append(a)
w.append(b)
assert len(c) - 1 == N and len(w) - 1 == N
dp = [[0]*(C+1) for _ in range(N+1)]
for i in range(1, N+1):
for j in range(C+1):
if c[i] > j: # 装不下
dp[i][j] = dp[i-1][j]
else:
dp[i][j] = max(dp[i-1][j], dp[i-1][j-c[i]]+w[i])
print(dp[N][C])
方法二:
好像超时了
# 自顶向下,先大问题再小问题,递归
N, C = map(int, input().split())
c = [0] # 每件物品的体积
w = [0] # 每件物品的价值
for i in range(N):
a, b = map(int, input().split())
c.append(a)
w.append(b)
assert len(c) - 1 == N and len(w) - 1 == N
dp = [[0]*(C+1) for _ in range(N+1)]
def solve(i, j):
global dp
if dp[i][j] != 0:
return dp[i][j]
if i == 0:
return 0
if c[i] > j: # 装不下
dp = solve(i-1, j)
else:
dp[i][j] = max(solve(i-1, j), solve(i-1, j-c[i])+w[i])
return dp[i][j]
print(solve(N, C))
N, M = map(int, input().split()) # 数组a和b的长度
a = [0] + list(map(int, input().split()))
b = [0] + list(map(int, input().split()))
m = max(N, M) + 1
dp = [[0]*m for _ in range(m)]
for i in range(1, N+1):
for j in range(1, M+1):
if a[i] != b[j]:
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
else:
dp[i][j] = dp[i-1][j-1] + 1
print(dp[N][M])
import itertools
s1 = input()[:-1]
s2 = input()[:-1]
a = [0] + list(s1)
b = [0] + list(s2)
N, M = len(a)-1, len(b)-1
m = max(N, M) + 1
dp = [[0]*m for _ in range(m)]
for i in range(1, N+1):
for j in range(1, M+1):
if a[i] != b[j]:
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
else:
dp[i][j] = dp[i-1][j-1] + 1
print(dp[N][M])
p = list(itertools.combinations(s1, dp[N][M]))
q = list(itertools.combinations(s2, dp[N][M]))
s = 0
for i in p:
for j in q:
if i == j:
s += 1
print(s)
A = input()
B = input()
a, b = len(A), len(B)
dp = [[0]*(b+1) for _ in range(a+1)]
#A为空:需要增加i个字符使A转化为B
for i in range(1, len(A)+1):
dp[i][0] = i
#B为空:需要减少i个字符使A转化为B
for i in range(1, len(B)+1):
dp[0][i] = i
for i in range(1, a+1):
for j in range(1, b+1):
if (A[i-1] == B[j-1]):
dp[i][j] = dp[i-1][j-1] # 不变
else: # 删除,插入,修改
dp[i][j] = min(dp[i-1][j]+1, dp[i][j-1]+1, dp[i-1][j-1]+1)
print(dp[a][b])
N, V = map(int, input().split()) # 物品数量,背包容量
w = [0] # 体积
v = [0] # 价值
for i in range(N):
a, b = map(int, input().split())
w.append(a)
v.append(b)
dp = [[0]*(V+1) for _ in range(N+1)]
for i in range(1, N+1):
for j in range(1, V+1):
if w[i] > j: # 装不下
dp[i][j] = dp[i-1][j]
else:
dp[i][j] = max(dp[i][j-w[i]]+v[i], dp[i-1][j])
# 和非完全背包仅有的区别: dp[i][j-w[i]]+v[i]
print(dp[N][V])
# 背包问题
T, M = map(int, input().split()) # 总时间,数目
t = [0] # 采摘某株草药的时间
v = [0] # 某株草药的价值
for i in range(M):
a, b = map(int, input().split())
t.append(a)
v.append(b)
dp = [[0]*(T+1) for i in range(M+1)]
for i in range(1, M+1):
for j in range(1, T+1):
if t[i] > j:
dp[i][j] = dp[i-1][j]
else:
dp[i][j] = max(dp[i-1][j], dp[i-1][j-t[i]]+v[i])
print(dp[M][T])
# 背包问题
N, m = map(int, input().split()) # 总钱数,物品个数
v = [0] # 价格
p = [0] # 重要度
for i in range(m):
a, b = map(int, input().split())
v.append(a)
p.append(b)
dp = [[0]*(N+1) for _ in range(m+1)]
for i in range(1, m+1):
for j in range(1, N+1):
if v[i] > j:
dp[i][j] = dp[i-1][j]
else:
dp[i][j] = max(dp[i-1][j], dp[i-1][j-v[i]]+p[i]*v[i])
print(dp[m][N])
n, m = map(int, input().split()) # n个同学传m次
dp = [[0]*(n+1) for _ in range(m+1)]
# dp[0][1] = 1
dp[1][2] = 1
dp[1][n] = 1
# dp[i][j]: 传了i次后,球在j同学手里有几种可能
for i in range(2, m+1):
for j in range(1, n+1):
if j == n:
dp[i][j] = dp[i-1][j-1] + dp[i-1][1]
elif j == 1:
dp[i][j] = dp[i-1][j+1] + dp[i-1][n]
else:
dp[i][j] = dp[i-1][j-1] + dp[i-1][j+1]
print(dp[m][1])
n, m = map(int, input().split()) # n种花m盆
a = list(map(int, input().split()))
assert len(a) == n
dp = [[0]*(m+1) for _ in range(n+1)]
# dp[i][j]: i种j盆时的方案数
# 只有一种花
for i in range(a[0]+1):
dp[1][i] = 1
# m = 0
for i in range(1, n+1):
dp[i][0] = 1
for i in range(2, n+1):
for j in range(1, m+1):
for k in range(a[i-1]+1):
if j - k >= 0:
dp[i][j] = (dp[i][j] + dp[i-1][j-k]) % int(1e6+7)
print(dp[n][m])
S = input()
T = input()
dp = [[int(1e3)]*(len(T)+1) for i in range(len(S)+1)]
# T为空
for i in range(len(S)+1):
dp[i][0] = 0
for i in range(1, len(S)+1):
for j in range(1, len(T)+1):
if S[i-1] == T[j-1]: # 字符串中的第i个字符和第j个字符
dp[i][j] = dp[i-1][j-1]
else:
dp[i][j] = min(dp[i-1][j-1]+1, dp[i-1][j])
print(dp[len(S)][len(T)])