• 分组背包问题


    题目链接acwing9


    解题思路图解

    通过解题思路我们可以写下如下代码

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=110;
    int f[N][N];  //只从前i组物品中选,当前体积小于等于j的最大值
    int v[N][N],w[N][N],s[N];   //v为体积,w为价值,s代表第i组物品的个数
    int n,m,k;
    
    int main(){
        cin>>n>>m;
        for(int i=1;i<=n;i++){
            cin>>s[i];
            for(int j=0;j<s[i];j++){
                cin>>v[i][j]>>w[i][j];  //读入
            }
        }
    
        for(int i=1;i<=n;i++){
            for(int j=0;j<=m;j++){
                f[i][j]=f[i-1][j];  //不选
                for(int k=0;k<s[i];k++){
                    if(j>=v[i][k])     f[i][j]=max(f[i][j],f[i-1][j-v[i][k]]+w[i][k]);  
                }
            }
        }
        cout<<f[n][m]<<endl;
    }
    

    代码优化
    因为只用到了第i-1列,所以可以仿照01背包问题的套路逆向枚举体积

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=110;
    int f[N];
    int v[N][N],w[N][N],s[N];
    int n,m,k;
    
    int main(){
        cin>>n>>m;
        for(int i=0;i<n;i++){
            cin>>s[i];
            for(int j=0;j<s[i];j++){
                cin>>v[i][j]>>w[i][j];
            }
        }
    
        for(int i=0;i<n;i++){
            for(int j=m;j>=0;j--){
                for(int k=0;k<s[i];k++){    //for(int k=s[i];k>=1;k--)也可以
                    if(j>=v[i][k])     f[j]=max(f[j],f[j-v[i][k]]+w[i][k]);  
                }
            }
        }
        cout<<f[m]<<endl;
    }
    
    作者:TaoZex
    链接:https://www.acwing.com/solution/content/3483/
    来源:AcWing
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    
  • 相关阅读:
    mysql操作
    Linux内核事件通知链学习
    C++双端队列学习
    tune的结果图是什么
    conda环境备份
    Could not load dynamic library 'libcudart.so.11.0';
    Unexpected error while saving file: xxx.ipynb database or disk is full
    友元函数与友元类
    构造函数初始化必须采用初始化列表的情况
    模型集成04-GMM
  • 原文地址:https://www.cnblogs.com/hnkjdx-ssf/p/14054929.html
Copyright © 2020-2023  润新知