• 动态规划- 背包问题总结(一)


    什么是动态规划

    动态规划通过额外的空间将已经搜索过的相似的结果(指某些具有相同性质解的集合)用一个数组存起来,所以DP中的状态转移看上去是某两三个值之间的推导,其实是某两三个集合之间的状态转移!

    常见的背包模型

    1. 01背包问题
    2. 完全背包问题
    3. 多重背包问题
    4. 分组背包问题

    01背包问题

    典型题例:

    有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。
    第 i 件物品的体积是 vi,价值是 wi。
    求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
    输出最大价值。

    示例 :

    输入:第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积
         接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值
    4 5
    1 2
    2 4
    3 4
    4 5
    

    思路
    在这里插入图片描述

    代码:
    朴素做法:

    #include 
    
    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];  //所有不选i的集合(左边集合)
                //  当前背包容量装不进第i个物品,则价值等于前i-1个物品
                if (j >= v[i]) f[i][j] = max(f[i][j], f[i -1][j - v[i]] + w[i]);
            }
    
        cout << f[n][m] << endl;
    
        return 0;
    }
    

    空间优化-等式变形

    #include 
    
    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 = m; j >= v[i]; j --) 
                f[j] = max(f[j], f[j - v[i]] + w[i]); 
    
    
        cout << f[m] << endl;
        return 0;
    }
    

    完全背包问题

    典型题例:

    有 N 种物品和一个容量是 V 的背包,每种物品都有无限件可用。
    第 i 种物品的体积是 vi,价值是 wi。
    求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
    输出最大价值。
    示例 :

    输入:第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。
         接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 种物品的体积和价值。
    4 5
    1 2
    2 4
    3 4
    4 5
    输出:
    10
    

    思路
    在这里插入图片描述

    代码:
    朴素做法

    #include 
    using namespace std;
    
    const int N = 1010;
    
    int n, m;
    int f[N][N];
    int v[N], w[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 = 1; j <= m; j ++){
    
                f[i][j] = f[i -1][j]; //先算前1~i-1
    
                if (j >= v[i]) 
                    f[i][j] = max(f[i][j], f[i][j - v[i]] + w[i]);
            }
    
        cout << f[n][m] << endl;
    
        return 0;
    }
    
    

    优化

    #include 
    using namespace std;
    
    const int N = 1010;
    
    int n, m;
    int f[N];
    int v[N], w[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] << endl;
    
        return 0;
    }
    

    传送门:动态规划- 背包问题总结(二)

    充电站
    推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习

  • 相关阅读:
    业务流程管理包括什么
    IDEA插件开发(12)---Dependencies
    ChatGPT带你飞,送3本《巧用ChatGPT快速搞定数据分析》
    演讲实录:大模型时代,我们需要什么样的AI算力系统?
    树状数组 逆序对
    centos7安装jdk8、maven3.9
    windows开发环境备份,再也不怕重装系统了
    jvm的内存调优
    C++ Reference: Standard C++ Library reference: C Library: cctype: ispunct
    普林斯顿10分钟剧本创作比赛
  • 原文地址:https://blog.csdn.net/weixin_53492721/article/details/127031374