美文网首页
动态规划---0-1 sack

动态规划---0-1 sack

作者: Tedisaname | 来源:发表于2018-11-03 14:40 被阅读13次

实验题目:0-1背包问题

问题描述:

面对每个物品,我们只有选择拿取或者不拿两种选择,不能选择装入某物品的一部分,也不能装入同一物品多次。

算法分析:

解决办法:声明一个 大小为 m[n][c] 的二维数组,m[i][j] 表示 在面对第 i 件物品,且背包容量为 j 时所能获得的最大价值 ,那么我们可以很容易分析得出 m[i][j] 的计算方法,
(1) j < w[i] 的情况,这时候背包容量不足以放下第 i 件物品,只能选择不拿
m[ i ][ j ] = m[ i-1 ][ j ]
(2) j > = w[i] 的情况,这时背包容量可以放下第 i 件物品,我们就要考虑拿这件物品是否能获取更大的价值。
如果拿取,m[ i ][ j ]=m[ i-1 ][ j-w[ i ] ] + v[ i ]。 这里的m[ i-1 ][ j-w[ i ] ]指的就是考虑了i-1件物品,背包容量为j-w[i]时的最大价值,也是相当于为第i件物品腾出了w[i]的空间。
如果不拿,m[ i ][ j ] = m[ i-1 ][ j ] , 同(1)
究竟是拿还是不拿,自然是比较这两种情况那种价值最大。

例子:6个物品,(重量,价值)分别为:(4,8),(6,10),(2,6),(2,3),(5,7),(1,2)。
背包容量 0 1 2 3 4 5 6 7 8 9 10 11 12
物品1 0 0 0 0 8 8 8 8 8 8 8 8 8
物品2 0 0 0 0 8 8 10 10 10 10 18 18 18
物品3 0 0 6 6 8 8 14 14 16 16 18 18 24
物品4 0 0 6 6 9 9 14 14 17 17 19 19 24
物品5 0 0 6 6 9 9 14 14 17 17 19 21 24
物品6 0 2 6 8 9 11 14 16 17 19 19 21 24

程序清单
#include <iostream> 
#include <cstring>
using namespace std;

const int N = 15;
int m[N][N];

int maxiu(int a, int b)
{
    return (a > b) ? a:b;
}

void KnapSack(int n,int c,int w[],int v[])
{
    int i,j;
    for(i = 1;i <= n; i++){
        for(j = 1; j <= c; j++){
            if(j >= w[i]){
                m[i][j] = max(m[i-1][j],m[i-1][j-w[i]]+v[i]);
            }
            else{
                m[i][j] = m[i-1][j];
            }
        } 
    } 
}

void printArray(int n,int c)
{
    int i , j;
    for(i = 1; i <= n; i++){
        for(j = 1; j <= c; j++){
            cout << m[i][j] << " ";
        }
        cout << endl;
    }
}
int main()
{
    int v[N] = {0,8,10,6,3,7,2};
    int w[N] = {0,4,6,2,2,5,1};
    int n = 6, c = 12;
    memset(m,0,sizeof(m));
    KnapSack(n,c,w,v);
    printArray(n,c);
    return 0;
}
复杂度分析:
    //该算法核心部分为:

    for(i = 1;i <= n; i++){
        for(j = 1; j <= c; j++){
            if(j >= w[i]){
                m[i][j] = max(m[i-1][j],m[i-1][j-w[i]]+v[i]);
            }

该算法的核心部分为两层for循环,外层for循环用来控制第i个物品,内层for循环用来控制当前背包的容量多少,所以算法的总的复杂度为:O(n*c).

实验总结:

本次实验主要还是练习了动态规划算法,解决的是0-1背包的问题,这是动态算法中比较基础较简单的一种,因此掌握该算法可以为以后更好的理解其他更深入的算法打好坚实的基础。该算法通过构造子问题的最优子结构,然后将大规模的问题一步一步的进行细化,不断地转化为规模更加小的子问题,通过子问题的求解,最终求出原问题的解。是一个自底向上不断求解的过程。

You can leave me a message if you find out any mistake in my diary, I'll correct it, thanks.

相关文章

  • 动态规划---0-1 sack

    实验题目:0-1背包问题 问题描述: 面对每个物品,我们只有选择拿取或者不拿两种选择,不能选择装入某物品的一部分,...

  • 初识动态规划

    0-1 背包问题 备忘录 动态规划-二维数组 动态规划-一维数组 0-1 背包问题升级版 回溯算法 动态规划-二维...

  • 动态规划

    0-1背包问题 自己实现的0-1背包问题的动态规划解法,先贴上吧,动态规划原理解释有空再写。

  • 算法3:动态规划

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

  • 数据结构与算法笔记day23:动态规划

    1初识动态规划 这节课的内容不涉及动态规划的理论,而是通过两个例子:0-1背包问题、0-1背包问题升级...

  • 动态规划-0-1背包问题

    动态规划-0-1背包问题 动态规划(dynamic programming)是解决多阶段决策问题常用的最优化理论,...

  • Algorithm

    bit manipulation 动态规划 0-1背包问题 寻找最小的k个数

  • 2018-11-14

    今天学了动态规划一些知识,着重看了一下动态规划之背包算法(主要是0-1算法和部分算法),关于动态规划的问题重点是建...

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

    经典动态规划背包问题最长子序列问题 1. 背包问题 1.1 0-1 背包问题 0-1 背包问题,描述如下: 上面...

  • lintcode-k数和

    动态规划(确定0-1背包、完全背包、多重背包)0-1背包:每个元素要么出现,要么不出现,逆序遍历,数组定义为:前i...

网友评论

      本文标题:动态规划---0-1 sack

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