第2题-模型推理量化加速优化问题

刷题链接:第2题-模型推理量化加速优化问题 - 题目详情 - CodeFun2000

为什么要用 np.minimum,用 min 不行吗?

  • min() 是给"普通数字"或者"纯列表"准备的。 如果你写 min(3, 5),它会返回 3。但如果你把两个数组 传给它,比如 min([1, 5, 9], [2, 4, 6]),Python 底层会像查字典比较字母顺序一样去比较它们。因为它看到第一位 1 < 2,它就会直接返回整个第一个数组 [1, 5, 9]!它根本不会去管后面的 5 和 4 谁大谁小。

  • np.minimum() 是专门给"数组进行单挑"准备的。 当你把两个 NumPy 数组交给它:np.minimum([1, 5, 9], [2, 4, 6]) 时,它会把两个数组并排摆在一起,逐个位置进行单挑

    • 第 1 位:1 和 2 单挑,留下 1

    • 第 2 位:5 和 4 单挑,留下 4

    • 第 3 位:9 和 6 单挑,留下 6

    • 最终返回一个全新的数组:[1, 4, 6]

python 复制代码
import sys
import numpy as np

def solve():
    input_data = sys.stdin.read().split()
    if not input_data:
        return
    
    L = int(input_data[0])
    T = float(input_data[1])

    '''
    round(number, ndigits=None)
    number:你要处理的数字。
    ndigits:你要保留的小数位数。如果不填,默认返回整数。
    '''
    S=100
    W = int(round(T*S))

    layers = []

    idx = 2
    for _ in range(L):
        K = int(input_data[idx])
        idx +=1
        options = []
        for _ in range(K):
            bit = input_data[idx]
            idx +=1
            loss = float(input_data[idx])
            w = int(round(loss*S))
            idx +=1
            mem = float(input_data[idx])
            idx+=1
            options.append((w,mem))
        
        layers.append(options)
    
    INF = float('inf')
    dp=np.full(W+1,INF,dtype=np.float64)
    '''
    numpy.full(shape, fill_value, dtype=None)
    # 2. 创建二维数组,2 行 3 列,全部填满 3.14
    b = np.full((2, 3), 3.14)
    # 结果: 
    # [[3.14 3.14 3.14]
    #  [3.14 3.14 3.14]]
    '''
    dp[0]=0

    for options in layers:
        ndp = np.full(W+1,INF,dtype=np.float64) # 准备一本全新的记事本
        # dp 是你上一关打完后,所有存活状态的最佳记录。
        # ndp(new dp)是你这一关的全新记事本,刚开始全是无穷大 INF。
        
        for w,men in options:
            if w<=W:
                candidate = dp[:W-w+1]+men
                ndp[w:] = np.minimum(ndp[w:],candidate)
        
        dp = ndp
    
    ans = np.min(dp)
    print(f"{ans:.2f}")

    

if __name__ =="__main__":
    solve()
    

更易懂但会慢一点的代码写法:

python 复制代码
import sys

def solve():
    # ---------- 1. 读取数据(和之前一样) ----------
    input_data = sys.stdin.read().split()
    if not input_data:
        return
    
    L = int(input_data[0])
    T = float(input_data[1])

    S = 100
    W = int(round(T * S)) # W 是我们能承受的最大伤害总额

    layers = []
    idx = 2
    for _ in range(L):
        K = int(input_data[idx])
        idx += 1
        options = []
        for _ in range(K):
            bit = input_data[idx]
            idx += 1
            loss = float(input_data[idx])
            w = int(round(loss * S))
            idx += 1
            mem = float(input_data[idx])
            idx += 1
            options.append((w, mem))
        layers.append(options)
    
    # ---------- 2. 准备初始记事本 ----------
    INF = float('inf')
    
    # 不用 Numpy,用纯 Python 列表创建一个有 W+1 个格子的记事本,全填满 INF
    dp = [INF] * (W + 1)
    dp[0] = 0.0  # 开局:受 0 点伤害,花 0 个金币

    # ---------- 3. 核心大循环(极其直白的三层嵌套) ----------
    
    # 第一层循环:一关一关地打
    for options in layers:
        # 每到新的一关,拿出一个全是 INF 的新记事本
        ndp = [INF] * (W + 1)
        
        # 第二层循环:看看这一关商店里卖哪些装备
        for w, mem in options:
            
            # 第三层循环:最关键的一步!
            # 我们挨个去翻看"上一关的旧记事本(dp)",看看里面哪些状态是活着的。
            for prev_w in range(W + 1):
                
                # 如果这个柜子里装的不是 INF,说明这是一个"真实的存活状态"
                if dp[prev_w] != INF:
                    
                    # 尝试穿上新装备:算算新伤害和新花费
                    curr_w = prev_w + w
                    curr_mem = dp[prev_w] + mem
                    
                    # 如果穿上后,总伤害没有超过我们的上限 W
                    if curr_w <= W:
                        # 那么,我们就看看这个总伤害对应的新柜子里,能不能放下更便宜的价格
                        # 如果当前的花费比新柜子里原有的花费更少,就替换它!(这就是找最便宜的)
                        if curr_mem < ndp[curr_w]:
                            ndp[curr_w] = curr_mem
                            
        # 这一关商店里的装备全试完了,交接记事本
        dp = ndp
    
    # ---------- 4. 输出结果 ----------
    # 找遍打完最后一关的记事本,看看哪个伤害值下,我们花的钱最少
    ans = min(dp)
    
    if ans == INF:
        print("No valid solution")
    else:
        print(f"{ans:.2f}")

if __name__ =="__main__":
    solve()
相关推荐
看海的四叔1 小时前
【Python】阿里云 DataWorks + ODPS + 钉钉联动实战:配合[特殊字符]全搞定
python·阿里云·api·odps·requests·openclaw
2401_865439633 小时前
HTML函数在低温环境下启动慢吗_温度对硬件启动影响【方法】
jvm·数据库·python
m0_3776182310 小时前
Golang怎么连接MySQL数据库_Golang MySQL连接教程【总结】
jvm·数据库·python
LN花开富贵11 小时前
【ROS】鱼香ROS2学习笔记一
linux·笔记·python·学习·嵌入式·ros·agv
weixin_5860614611 小时前
C#怎么通过反射获取类属性_C#如何动态读取元数据【进阶】
jvm·数据库·python
Jurio.11 小时前
本机开发 + 多机执行的极简远端运行工具
linux·git·python·github·远程工作
skywalk816311 小时前
pytest测试的时候这是什么意思?Migrating <class ‘kotti.resources.File‘>
前端·python
overmind11 小时前
oeasy Python 121[专业选修]列表_多维列表运算_列表相加_列表相乘
java·windows·python
房开民11 小时前
可变参数模板
java·开发语言·算法