美文网首页动态规划
完全背包--二维数组

完全背包--二维数组

作者: 本小白瞎胡闹 | 来源:发表于2017-11-07 17:30 被阅读98次

完全背包问题是在01背包问题进行些改变,其大意为:
有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
可以发现,它与01背包的区别在于这句话“每种物品都有无限件可用”,即对于特定容量,每件物品最多可放V/c[i]件,所以,将01背包的dp代码改为:

sum[i][j] = Max(sum[i - 1][j], sum[i - 1][j - k * c[i]] + k * v[i])

sum[i - 1][j - k * c[i]] + k * v[i]表示前i-1种物品中选取若干件物品放入剩余空间为j - k * c[i]的背包中所能得到的最大价值加上k件第i种物品,其中的k为选择i物品的数量;
于是,可以用三个循环完成这个步骤:

    for(i = 1;i <= n;i++)
        for(j = 1;j <= t;j++)
            for(k = 0;k * c[i] <= j;k++)
                sum[i][j] = Max(sum[i - 1][j], sum[i - 1][j - k * c[i]] + k * v[i]);

接下来可以做些简单的优化

设sum[i][j]表示出在前i种物品中选取若干件物品放入容量为j的背包所得的最大价值。那么对于第i种物品的出现,我们对第i种物品放不放入背包进行判断。
如果不放,那么sum[i][j]=sum[i-1][j];
如果确定放,背包中应该已经出现了至少一件第i种物品,所以sum[i][j]中至少应该出现一件第i种物品,即sum[i][j]=sum[i][j-c[i]]+v[i]
为什么会是sum[i][j-c[i]]+v[i]?
因为在前面已经最大限度的放了第i件物品,现在如果还能放,那就放这最后的一件,也可以理解为前面已经往背包中放入了第i件物品,每一次只增加一件的往背包里放,而且只能增加一件,多了放不下。
举个例子
有容量为5的背包,有三个物品:
物品a,价值为2,重量为1
物品b,价值为3,重量为2
物品c,价值为4,重量为5

再次拿出下图

1111.png
同样按照01背包中填表方式,将数值填入,表格。
再次强调,

sum[i][j] = Max(sum[i - 1][j], sum[i][j - k * c[i]] + k * v[i])

完整代码如下:

#include <stdio.h>
int sum[1001][1001];//sum[i][j]放入第i个物品,j空间的背包最大重量
int Max(int a,int b);//判断大小
void init(int b);//初始化背包
void scok(int n,int t,int* c,int* v);//核心判断
int Max(int a,int b)
{
    if(a > b)
        return a;
    else
        return b;
}
void init(int b)
{
        for(int j = 0;j <= b;j++)
        {
            sum[0][j] = 0;
        }
}
void scok(int n,int t,int* c,int* v)
{
    int i,j;
    init(n);
    for(i = 1;i <= n;i++)
    {
        for(j = 1;j <= t;j++)
        {
            if(j >= c[i])
                sum[i][j] = Max(sum[i - 1][j], sum[i][j - c[i]] + v[i]);
            else
                sum[i][j] = sum[i - 1][j];
        }
    }
    printf("%d\n",sum[n][t]);
}
int main(){
    int n,t;
    int c[1003],v[1003];
    scanf("%d %d",&n,&t);
    for(int i = 1;i <= n;i++)
        scanf("%d %d",&c[i],&v[i]);
    scok(n, t, c, v);
    return 0;
}

相关文章

  • 剑指 Offer II 103. 最少的硬币数目

    动态规划。完全背包 二维数组 转一维数组

  • 完全背包--二维数组

    完全背包问题是在01背包问题进行些改变,其大意为:有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物...

  • 初识动态规划

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

  • 1.1、动态规划

    用一纬数组记录,如果不行就用二维,大部分是二维。1、背包问题01背包:有n件物体,容量为v的背包,使物品价值最大。...

  • 背包入门

    背包,是动态规划里一类典型的问题,主要有:01背包,完全背包,多重背包,混合背包,二维费用背包,分组背包,有依赖背...

  • 背包九讲学习笔记

    从上到下顺序遍历 01背包问题 使用二维数组 01背包问题 空间复杂度优化 使用一维数组 重点:此处必须从后往前遍...

  • lintcode-k数和

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

  • 动态规划常见面试题

    子序列类型编辑距离 最长递增子序列 最大子数组 最长公共子序列 背包问题0-1背包问题 子集背包问题 完全背包问题...

  • Day08

    二维数组 二维数组格式 二维数组初始化 二维数组的遍历 二维数组内存存储细节 二维数组与函数注意点: 主要是看函数...

  • 01背包问题--二维数组

    01背包问题是比较简单的动态规划问题,题目大意为:有N件物品和一个容量为V的背包。每种物品均只有一件,第i件物品的...

网友评论

    本文标题:完全背包--二维数组

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