美文网首页
动态规划02

动态规划02

作者: 欣悦的灵魂 | 来源:发表于2017-08-02 22:33 被阅读0次

今天主要看一下经典的背包问题:

01背包Charm Bracelet

有N件物品和一个容积为M的背包。第i件物品的体积w[i] ,价值是d[i]。求解将哪些物品装入背包可使价值总和 最大。每种物品只有一件,可以选择放或者不放 (N<=3500,M <= 13000)

 example:
   总体积:6          物品数:4
   体积:  1    2    3     2
   价值:  4    6    12    7
   取舍:  1    0    1     1
 结果:23

我们设V[i][j]表示前i个物品,体积不超过j,取得的最大价值。于是:

            V[i][j] = max(V[i - 1][j], V[i - 1][j - w[i]]+d[i])//表示在满足不超过j的情况下,对第i个物品进行取舍
#include <iostream>
#include <algorithm>
#include <string.h>
usingnamespacestd;

int main() {
    int N,M;
    cin>>N>>M;
    int W[N + 1],D[N + 1];//W是重量,D是期望度
    for (int i = 1; i <= N; i++) {
        cin>>W[i]>>D[i];
    }
    int MaxDesire[N + 1][M + 1];
    memset(MaxDesire, 0, sizeof(MaxDesire));
    for (int i = 1; i <= M; i++) {
        if (i >= W[1]) {
            MaxDesire[1][i] = D[1];
        } else MaxDesire[1][i] = 0;
    }
    for (int i = 2; i <= N; i++) {
        for (int j = 0; j <= M; j++) {
            MaxDesire[i][j] = MaxDesire[i - 1][j];
            if (j - W[i] >= 0) {
                MaxDesire[i][j] = max(MaxDesire[i - 1][j - W[i]] + D[i], MaxDesire[i - 1][j]);
            }
        }
    }
    cout<<MaxDesire[N][M];
    return0;
}

但是,这个题目如果这么开二维数组的话,就会超内存,我们得想一种更节省内存的办法。
即考虑:对这些物品而言,不超过j能达到的最大价值,我们设成MaxV[j]。动态规划,要求无后效性,而对前i种物品考虑的取舍,对i种以后的物品取舍,有无后效性(对比,三角形那的滚动数组)

#include <iostream>
#include <algorithm>
#include <string.h>
usingnamespacestd;

int main() {
    int N,M;
    cin>>N>>M;
    int W[N + 1],D[N + 1];//W是重量,D是期望度
    for (int i = 1; i <= N; i++) {
        cin>>W[i]>>D[i];
    }
    int MaxDesire[M + 1];
    memset(MaxDesire, 0, sizeof(MaxDesire));
    for (int i = 1; i <= N; i++) {
        for (int j = M; j >= W[i]; j--) {
            MaxDesire[j] = max(MaxDesire[j - W[i]] + D[i], MaxDesire[j]);
        }
    }
    cout<<MaxDesire[M]<<endl;
    return0;
}
神奇的口袋

神奇的口袋(百练2755)

有一个神奇的口袋,总的容积是40,用这个口袋可以变出一些物品,这些物品的总体积必须是40。
John现在有n(1≤n ≤ 20)个想要得到的物品,每个物品的体积分别是a1,a2......an。John可以从这些物品中选择一些,如果选出的物体的总体积是40,那么利用这个神奇的口袋,John就可以得到这些物品。现在的问题是,John有多少种不同的选择物品的方式
  这道题有两种解法,一种是传统的递归式解法,另外一种是可达型动态规划,设计更加巧妙一些,当作练习题。【Tips:一维动规】
  我们设Ways[i][j]表示用前j件物品凑出i体积的方法数,而题目要求我们求的就是Ways[40][N],那么:

    *  如果前j-1件物品可以组成i, 那么前j件物品也可以组成i
    *  如果前j-1件物品可以组成i-a[j](所以必须是i-a[i]大于零的情况),那么前j件物品也可以组成i
#include <iostream>
#include <algorithm>
#include <string.h>
usingnamespacestd;

int main() {
   int t;
   cin>>t;
   int A[t];
   int Ways[41][t + 1];
   memset(Ways, 0, sizeof(Ways));
   for (int i = 0; i < t; i++) {
       cin>>A[i];
   }
   for (int i = 0; i <= t; i++) {
       Ways[0][i] = 1;
   }
   for (int i = 0; i <= 40; i++) {
       for (int j = 1; j <= t; j++) {
           Ways[i][j] = Ways[i][j - 1];
           if (i - A[j - 1] >= 0) {
               Ways[i][j] = Ways[i][j - 1] + Ways[i - A[j - 1]][j - 1];
           }
       }
   }
   for (int i = 0; i <= 40; i++) {
       for (int j = 0; j <= t; j++) {
           cout<<Ways[i][j]<<" ";
       }
       cout<<i<<endl;
   }
   cout<<Ways[40][t];
   return0;
}

练习题:

用一维动规解决神奇的口袋
最佳加法表达式(百练上的版本要求高精度)

相关文章

  • 动态规划02

    今天主要看一下经典的背包问题: 01背包Charm Bracelet 有N件物品和一个容积为M的背包。第i件物品的...

  • Algorithm进阶计划 -- 动态规划(上)

    动态规划动态规划的基本原理动态规划的运用 1. 动态规划的基本原理 动态规划(Dynamic Programmi...

  • 4. 动态规划算法

    1. 动态规划算法总结2. 漫画:什么是动态规划?3.算法之动态规划4. 动态规划-算法

  • 动态规划 Dynamic Programming

    从运筹学和算法的角度综合介绍动态规划 算法分类总结动态规划与静态规划的关系浅析静态规划和动态规划动态规划解非线性规...

  • 《数据结构与算法之美》27——初识动态规划

    前言 今天开始学习动态规划,一共有三节,分别是:初识动态规划、动态规划理论、动态规划实战。今天这一节就是初识动态规...

  • 算法3:动态规划

    5.动态规划5.1 什么是动态规划?5.2 自底向上的动态规划:5.3 自顶向下的动态规划5.4 0-1背包问题:...

  • 动态规划入门02

    递归转为递推 从最后一行开始向上反推例如对于:573 88 1 02 7 4 44 5 2 6 5 倒数第二行的每...

  • 动态规划-02完全背包

    问题描述 有n个物品,它们有各自的体积和价值,现有给定容量V的背包,每种物品都就可以选择任意数量,如何让背包里装入...

  • 动态规划

    动态规划(Dynamic Programming) 本文包括: 动态规划定义 状态转移方程 动态规划算法步骤 最长...

  • Dynamic Programming(动态规划)类算法分析随笔

    #动态规划 关于动态规划,先摘一段[wiki][1]的描述: ``` 动态规划(英语:Dynamic progra...

网友评论

      本文标题:动态规划02

      本文链接:https://www.haomeiwen.com/subject/esiylxtx.html