A. 财富评估项目
模拟
from typing import List
def solution(financials: List[List[int]]) -> int:
return max(map(sum, financials))
B. 礼物价值
多重背包问题,可以使用二进制优化
from typing import List
def solution(giftPackages: List[List[int]], eventCapacity: int) -> int:
m = eventCapacity
f = [0] * (m + 1)
for x, y in giftPackages:
k = 1
while x >= k:
for i in range(m, k - 1, -1):
f[i] = max(f[i], f[i - k] + y * k)
x -= k
k *= 2
if x > 0:
k = x
for i in range(m, k - 1, -1):
f[i] = max(f[i], f[i - k] + y * k)
return f[-1]
C. 最优远足问题
直接最短路就行
from typing import List
from heapq import heappush, heappop
def solution(heights: List[List[int]]) -> int:
g = heights
n = len(g)
m = len(g[0])
vis = [[0] * m for _ in range(n)]
dis = [[0] * m for _ in range(n)]
Q = [(0, 0, 0)]
while Q:
d, x, y = heappop(Q)
if vis[x][y]:
continue
vis[x][y] = 1
dis[x][y] = d
for dx, dy in (-1, 0), (0, 1), (1, 0), (0, -1):
i = x + dx
j = y + dy
if 0 <= i < n and 0 <= j < m and not vis[i][j]:
heappush(Q, (max(d, abs(g[i][j] - g[x][y])), i, j))
return dis[n - 1][m - 1]
D. 画作
假设前 i 个数组成的排列能从入口看见 j 幅画作,这里可以假设排列为
考虑怎么得到前 i + 1 个数组成的排列 ,可以先将任意一个 的所有项先加一,然后从 i + 1 个空位中选择一个插入 1,即可保证不重不漏;
当插入到最前面时,能看见的画作数量会多一个,否则插入到其它 i 个空位时,能看见的画作数量不变
得到转移公式如下
from typing import List
p = 10 ** 9 + 7
def solution(n: int, k: int) -> int:
f = [[0] * (k + 1) for _ in range(n + 1)]
f[0][0] = 1
for i in range(1, n + 1):
for j in range(1, min(i, k) + 1):
f[i][j] = f[i - 1][j - 1] + f[i - 1][j] * (i - 1)
f[i][j] %= p
return f[n][k]