c语言算法—背包问题进阶型(含有两个约束项)

原创 2017年03月28日 14:35:30

在之前的01背包问题中,我们可以发现约束项都只有一个,下面我们来探讨两个约束项的情况;

首先,我们考虑使用一维还是二维来表达:在有一个约束项时,我们需要二维,因为横向表示物品数,而竖向表示约束项的改变;所以我们发现,当有两个约束项的时候,不能再使用二维数组的方式了;

所以,我们决定使用一维数组;再考虑,一维数组时,用数组的下标来表示约束项的改变,那么当有两个约束项的时候,明显下标不够,那么什么能用来表示两个约束项呢?

那就是二维数组。它包含的两个下标,正好分别对应了每个约束项;

所以,经过这样的思维流程,我们可以发现,其实含有两个约束项的二维数组实质上是由一维数组的表达算法衍化而来;

那么,我们在书写代码的时候,就要注意了,最大的循环应该依旧是物体的个数,因为不管怎样,都要遍历完所有的物品,即:

for(int k=1;k<=n;++k)

然后我们需要对两个约束项的0-m都进行遍历,即:

for(int i=m1;i>=0;--i)
for(int j=m2;j>=0;--j)

因为此方式是由一维数组的放大衍化而来的,所以遍历的时候,只能逆序遍历;

然后,我们应该考虑到,每次进行更新的时候,不能只对一个约束项进行控制,而是两个一起考虑,所以if条件应该修改为:

if(j>=a[k]&&i>=b[k])

而在更新的时候,同样应该进行两项的下标更新:

f[i][j]=max(f[i][j],f[i-b[k]][j-a[k]]+c[k]);

此代码主要部分已差不多说完,上完整代码:

#include<stdio.h>
#include<malloc.h>
#define max(a,b) (a>b? a:b) 
int f[3000][3000];
int *a,*b,*c;
int main()
{
    int m,v,n;
    scanf("%d%d%d",&m,&v,&n);
    a=(int *)malloc(sizeof(int)*(n+1));
    b=(int *)malloc(sizeof(int)*(n+1));
    c=(int *)malloc(sizeof(int)*(n+1));
    for(int i=1;i<=n;++i)
    scanf("%d%d%d",&a[i],&b[i],&c[i]);
    for(int k=1;k<=n;++k)
    for(int i=v;i>=0;--i)
    for(int j=m;j>=0;--j)
    {
        if(j>=a[k]&&i>=b[k])
        f[i][j]=max(f[i][j],f[i-b[k]][j-a[k]]+c[k]); 
    }

    printf("%d",f[v][m]);
    return 0;
} 
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Vernon917/article/details/67636566

限定条件不止一种的背包问题

对于正常的背包问题,只有一个限定条件——背包容量不超过多少,而有些背包问题有多重限定条件,比如NASA的食物计划这道题,有体积和质量这两个限定条件。 对于这种问题,其实是和正常的背包问题是差不多的,...
  • kyriesnow
  • kyriesnow
  • 2015-03-14 09:45:42
  • 840

二维背包问题

问题:二维背包问题是指每件物品都具有  两种条件,选择这件物品必须要满足这两个条件,在选择物品的时候必须保证这两个条件都满足背包限制的两个条件,求选择物品可以得到最大的权重。设第i件物品所需的两种限制...
  • hpugym
  • hpugym
  • 2015-02-19 20:48:17
  • 1336

谈谈2018华为精英挑战赛

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;背景介绍云平台为了满足不同租户的需求,提供了一种可随时自助获取、可弹性伸缩的云服务器,即弹性云服务器(Elastic C...
  • u012017783
  • u012017783
  • 2018-04-14 23:55:26
  • 74

华为2018软件精英挑战赛指导(含伪代码)

  • 2018年03月16日 11:48
  • 21KB
  • 下载

2018华为软件精英挑战赛实况记录

       今天想写一篇博客记录一下自己参加华为软挑的过程,估计会在接下来一个月陆续更新。题目其实几天前就看过了,代码也写了两天,不过报名还是今天的事。       今年的题目相对还是比较好理解的,...
  • xbb123456rt
  • xbb123456rt
  • 2018-03-18 22:11:07
  • 477

2017华为软件精英挑战赛思路分析

声明:这篇博客仅用于(zhang)交(fang)流(wen)学(liang)习,让大家更快的熟悉赛题,不会涉及到具体的算法细节,所以不会影响到前排同学的排名,请不用担心。题目大意有一个无向网络,网路的...
  • mmy1996
  • mmy1996
  • 2017-03-21 15:59:14
  • 14931

动态规划之背包问题(二):完全背包问题

完全背包问题 问题描述 在上一篇里,有关01背包问题,我们在状态转移函数、是否需要放满、利用一维数组优化空间复杂度几个方面做了阐述。本篇要解决的是完全背包问题,描述如下: 有N种物品和一个容量为...
  • siyu1993
  • siyu1993
  • 2016-10-19 14:09:49
  • 1420

2017 华为软件精英挑战赛

官方题目中的例子,但是我数了下只有44条边,用于测试吧28 44 12 100 0 1 20 1 0 2 16 1 0 3 13 1 0 6 13 2 0 7 25 2 0 8 36 2 0 9 ...
  • firenet1
  • firenet1
  • 2017-03-19 18:40:30
  • 16641

多维多选的背包问题

0-1背包问题是一类典型的组合优化问题,它要求找出n个物体的一个子集使其尽可能的装满容量为W的背包。他本质上是一个只有一个约束条件的0-1规划问题,在计算理论上属于NP完全问题,计算复杂性为o(2^n...
  • u012679583
  • u012679583
  • 2017-11-12 15:47:18
  • 1248

背包问题

背包问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述现在有很多物品(它们是可以分割的),我们知道它们每个物品的单位重量的价值v和重量w(1...
  • l2533636371
  • l2533636371
  • 2017-08-01 09:40:39
  • 55
收藏助手
不良信息举报
您举报文章:c语言算法—背包问题进阶型(含有两个约束项)
举报原因:
原因补充:

(最多只允许输入30个字)