1 条题解

  • 0
    @ 2026-1-27 21:31:04
    #include <bits/stdc++.h>
    using namespace std;
    
    // [1] m-目标花费金额(需花完的钱数);n-书的种类数(每种最多买1本)
    int m,n;
    // [2] arr数组-存储每种书的价格(下标1~n)
    int arr[2100];
    // [3] dp数组-动态规划状态,dp[j]表示恰好花j元的买书方案数,用long long防止方案数过大溢出int
    long long dp[11000]={};
    
    int main() {
        // 问题分析:01背包计数问题,每种书最多买1本,求恰好花完M元的买书方案数
        // 解题步骤:1.初始化dp[0]=1(花0元的方案为1种:不买任何书);2.逆序遍历每种书,更新dp[j] += dp[j-arr[i]](选当前书的方案数=花j-arr[i]元的方案数);
        //          3.最终dp[m]即为恰好花完M元的方案数
        
        cin>>n>>m;  // [4] 读取书的种类数n和目标花费金额m
        for(int i=1;i<=n;i++) cin>>arr[i];  // [5] 读取每种书的价格,存入arr数组
        
        dp[0]=1;  // [6] 初始化:花0元的方案数为1(选择不买任何书)
        
        // 01背包核心循环:遍历每种书,逆序更新方案数(保证每种书仅被选一次)
        for(int i=1;i<=n;i++){  // [7] 外层循环:遍历每种书(每种书最多买1本)
            // 内层循环:逆序遍历金额(避免同一本书被重复计算,符合01背包“每个物品仅选一次”的要求)
            for(int j=m;j>=arr[i];j--){
                // [8] 状态转移:不选当前书时dp[j]不变;选当前书时,方案数增加dp[j-arr[i]](花j-arr[i]元的方案数,加上当前书的价格正好花j元)
                dp[j] = dp[j] + dp[j-arr[i]];
            } 	
        }
        cout<<dp[m];  // [9] 输出恰好花完m元的买书方案数
        return 0;
    }
    
    • 1

    信息

    ID
    1353
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者