AcWing算法基础课---第五讲动态规划

背包问题

  1. 01背包
    (1). 二维dp

    #include<iostream>
    
    using namespace std;
    
    const int N = 1010;
    int m, n;
    int V[N], W[N];
    int f[N][N]; //f[i][j]表示从i个物品中选,容量不超过j的最大价值
    
    int main()
    {
        cin >> n >> m;
        
        for (int i = 1; i <= n; i ++) cin >> V[i] >> W[i];
        
        for (int i = 1; i <= n; i ++)
        {
            for (int j = 0; j <= m; j ++) 
            {
                f[i][j] = f[i - 1][j]; //不包含i肯定存在
                if (j >= V[i]) f[i][j] = max(f[i][j], f[i - 1][j - V[i]] + W[i]); //包含i可能不存在
               
            }
        }
        
        cout << f[n][m];
        return 0;
    }
    

    (2). 压缩为一维dp

    #include<iostream>
    
    using namespace std;
    
    const int N = 1010;
    int m, n;
    int V[N], W[N];
    int f[N]; //f[i][j]表示从i个物品中选,容量不超过j的最大价值
    
    int main()
    {
        cin >> n >> m;
        
        for (int i = 1; i <= n; i ++) cin >> V[i] >> W[i];
        
        for (int i = 1; i <= n; i ++)
            for (int j = m; j >= V[i]; j --) 
            {
                f[j] = max(f[j], f[j - V[i]] + W[i]); //包含i可能不存在
               
            }
        
        
        cout << f[m];
        return 0;
    }
    
  2. 完全背包
    (1). 二维

    #include<iostream>
    
    using namespace std;
    
    const int N = 1010;
    
    int n, m;
    int v[N], w[N];
    int f[N][N];
    
    int main()
    {
        cin >> n >> m;
        
        for (int i = 1; i <= n; i ++) cin >> v[i] >> w[i];
        
        for (int i = 1; i <= n; i ++) 
            for (int j = 0; j <= m; j ++) 
            {
                f[i][j] = f[i - 1][j];
                if (j >= v[i]) f[i][j] = max(f[i][j], f[i][j - v[i]] + w[i]);
            }
            
        cout << f[n][m];
        return 0;
    }
    

    (2). 一维

    #include<iostream>
    
    using namespace std;
    
    const int N = 1010;
    
    int n, m;
    int v[N], w[N];
    int f[N];
    
    int main()
    {
        cin >> n >> m;
        
        for (int i = 1; i <= n; i ++) cin >> v[i] >> w[i];
        
        for (int i = 1; i <= n; i ++) 
            for (int j = v[i]; j <= m; j ++) 
                f[j] = max(f[j], f[j - v[i]] + w[i]);
            
            
        cout << f[m];
        return 0;
    }
    
  3. 多重背包

    #include<iostream>
    
    using namespace std;
    
    const int N = 10010;
    
    int n, m;
    int v[N], w[N]; 
    int f[N]; 
    
    int main()
    {
        cin >> n >> m;
        
        int cnt = 0;
        for (int i = 1; i <= n; i ++) 
        {
            int a, b, s;
            cin >> a >> b >> s;
            int k = 1;
            
            //打包
            while (k <= s) 
            {
                cnt ++;
                v[cnt] = a * k;
                w[cnt] = b * k;
                s -= k;
                k *= 2;
            }
            
            if (s > 0) 
            {
                cnt ++;
                v[cnt] = a * s;
                w[cnt] = b * s;
            }
        }
        
        n = cnt;
        
        for (int i = 1; i <= n; i ++)
            for (int j = m; j >= v[i]; j --) 
                f[j] = max(f[j], f[j - v[i]] + w[i]);
                
        cout << f[m];
        
        return 0;
    }
    
  4. 分组背包

    #include <iostream>
    
    using namespace std;
    
    const int N = 110;
    
    int n, m;
    int v[N][N], w[N][N], s[N], f[N];
    
    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 = m; j >= 0; j --)
                for (int k = 0; k < s[i]; k ++)
                    if (v[i][k] <= j) //判断是否能装下!!!
                        f[j] = max(f[j], f[j - v[i][k]] + w[i][k]);
                    
        cout << f[m];
        
        return 0;
    }
    
posted @   hjy94wo  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示