从0开始学算法——第十八天(分治算法练习)

写在开头的话

学习了今天的基础知识,让我们来做几道题来练练手吧。(题目是别的地方扒来的,参考答案是我自己写的,肯定不是最优解,有更好的方法欢迎评论区交流)

题目一------汉诺塔

题目二------情景题

题目三------蛋糕美味值

参考答案

第一题参考答案(Python版)

python 复制代码
def hanoi_tower(n, m, source, target, auxiliary, step_count, current_step):
    """
    n: 当前要移动的盘子数量
    m: 目标步数
    source: 源柱子
    target: 目标柱子
    auxiliary: 辅助柱子
    step_count: 当前已移动步数
    current_step: 当前步数的引用列表(用于记录当前步数)
    """
    if n == 0:
        return step_count
    
    # 移动n-1个盘子从source到auxiliary
    step_count = hanoi_tower(n-1, m, source, auxiliary, target, step_count, current_step)
    
    # 如果已经找到目标步数,直接返回
    if current_step[0] is not None:
        return step_count
    
    # 移动第n个盘子
    step_count += 1
    if step_count == m:
        current_step[0] = f"#{n}: {source}->{target}"
        return step_count
    
    # 移动n-1个盘子从auxiliary到target
    step_count = hanoi_tower(n-1, m, auxiliary, target, source, step_count, current_step)
    
    return step_count

def main():
    # 读取输入
    N, M = map(int, input().split())
    
    # 计算最少移动步数
    min_steps = 2**N - 1
    
    # 查找第M步的移动
    current_step = [None]
    total_steps = hanoi_tower(N, M, 'A', 'C', 'B', 0, current_step)
    
    # 输出结果
    if current_step[0]:
        print(current_step[0])
    else:
        print("#Invalid step")
    
    print(min_steps)

if __name__ == "__main__":
    main()

第二题参考答案(Python版)

python 复制代码
import sys
from functools import lru_cache

MOD = 998244353

def modinv(x: int) -> int:
    """返回x在模MOD下的逆元,MOD为质数"""
    return pow(x, MOD - 2, MOD)

def solve() -> None:
    data = sys.stdin.read().strip().split()
    if not data:
        return
    it = iter(data)
    n = int(next(it))
    k = int(next(it)) - 1          # 转为0-indexed
    a = [int(next(it)) for _ in range(n)]

    damages = [5, 4, 3, 2, 1]      # 依次造成的伤害值

    @lru_cache(maxsize=None)
    def dfs(i: int, state: tuple) -> int:
        """
        返回:从当前状态继续,最终第k个随从死亡的概率(模MOD)
        i: 已经完成了i次伤害 (0 <= i <= 5)
        state: 长度为n的元组,表示每个随从的当前血量(死亡则为0)
        """
        if i == 5:                 # 所有伤害完成
            return 1 if state[k] <= 0 else 0

        # 找出所有存活随从的索引
        alive = [idx for idx in range(n) if state[idx] > 0]
        if not alive:              # 没有存活随从,法术终止
            return 1 if state[k] <= 0 else 0

        d = damages[i]             # 本次伤害值
        m = len(alive)
        inv_m = modinv(m)          # 存活数的逆元
        res = 0
        for idx in alive:
            new_state = list(state)
            new_hp = state[idx] - d
            if new_hp < 0:
                new_hp = 0
            new_state[idx] = new_hp
            res = (res + dfs(i + 1, tuple(new_state))) % MOD
        res = res * inv_m % MOD
        return res

    ans = dfs(0, tuple(a))
    print(ans)

if __name__ == "__main__":
    solve()

第三题参考答案(Python版)

python 复制代码
def max_taste_sum():
    import sys
    
    # 读取输入
    data = sys.stdin.read().strip().split()
    n, k = map(int, data[:2])
    tastes = list(map(int, data[2:]))
    
    max_sum = 0
    
    # 使用位运算枚举所有子集
    for mask in range(1 << n):  # 枚举0到2^n-1
        current_sum = 0
        # 检查mask的每一位,如果为1则选择对应蛋糕
        for i in range(n):
            if mask & (1 << i):
                current_sum += tastes[i]
        
        # 如果当前和小于k且大于已知最大值,则更新
        if current_sum < k and current_sum > max_sum:
            max_sum = current_sum
    
    print(max_sum)

if __name__ == "__main__":
    max_taste_sum()
相关推荐
深圳雨林凯AI21 分钟前
图案裂变的“风格归一化“设计思路:主体保得住,画风才拉得齐|雨林凯AI技术笔记
人工智能·笔记
北域码匠22 分钟前
高通滤波算法深度解析(High-Pass Filter)
stm32·算法·c#·数字信号处理·嵌入式开发·滤波算法·高通滤波
问天_观心36 分钟前
大模型微调学习(二)
人工智能·python·深度学习·学习·语言模型·transformer
指掀涛澜天下惊1 小时前
强化学习进阶篇八 策略梯度算法
深度学习·学习·算法·强化学习
乌萨奇也要立志学C++1 小时前
【洛谷】kmp算法
开发语言·算法
禹凕1 小时前
Dijkstra算法详解与应用
python·算法
star learning white1 小时前
STM32入门学习5
stm32·嵌入式硬件·学习
传奇开心果编程1 小时前
【Rust入门知识点学与练】第4课:条件判断 if / else
开发语言·学习·rust
lifallen2 小时前
Skill 的生命周期:问题消失以后
人工智能·学习·ai·ai编程
千谦阙听2 小时前
C++类和对象(中):默认成员函数、构造与析构、拷贝构造、运算符重载
开发语言·c++·学习