1 条题解

  • 0
    @ 2026-5-7 20:08:12

    2个一维数组滚动:

    #include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    int main(){
        int m,n;
        if(!(cin>>m>>n)) return 0;
        vector<int> w(n),v(n);
        for(int i=0;i<n;i++) cin>>w[i]>>v[i];
        // p代表上一轮(前i-1件物品)的状态,c代表当前轮(前i件物品)的状态
        vector<ll> p(m+1,0),c(m+1,0);
        for(int i=0;i<n;i++){
            // 因为数据是从p数组读取并写入c数组,所以j从小到大或从大到小遍历均可
            for(int j=0;j<=m;j++){
                if(j>=w[i]){
                    // 状态转移方程:取“不放第i件物品”和“放第i件物品”中的最大值
                    c[j]=max(p[j], p[j-w[i]]+v[i]);
                }else{
                    // 容量不足,直接继承上一轮该容量下的最大价值
                    c[j]=p[j];
                }
            }
            // 核心滚动逻辑:处理完一件物品后,将当前状态同步给p,为下一件物品做准备
            p=c;
        }
        // 输出在背包容量为M时的最大价值
        cout<<p[m]<<endl;
        return 0;
    }
    
    • 1

    信息

    ID
    1149
    时间
    1000ms
    内存
    128MiB
    难度
    5
    标签
    递交数
    32
    已通过
    16
    上传者