豆包MarsCode 算法竞技赛 Vol.2 题解及代码(python)

243 阅读1分钟

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 幅画作,这里可以假设排列为 Pi=[p1,p2,...,pi]P_i = [p_1, p_2, ..., p_i]

考虑怎么得到前 i + 1 个数组成的排列 Pi+1P_{i+1},可以先将任意一个 PiP_i 的所有项先加一,然后从 i + 1 个空位中选择一个插入 1,即可保证不重不漏; 当插入到最前面时,能看见的画作数量会多一个,否则插入到其它 i 个空位时,能看见的画作数量不变

得到转移公式如下

dp[i][j]= { 1if i=j=0 dp[i1][j1]+dp[i1][j]×(i1)if ij1 \mathrm{dp}[i][j] =  \begin{cases}  1 & \text{if } i = j = 0 \\  dp[i - 1][j - 1] + dp[i - 1][j] \times (i - 1) & \text{if } i \ge j \ge 1 \end{cases}
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]