C语言动态规划多种背包问题分析讲解

C语言动态规划多种背包问题分析讲解

背包问题介绍

背包问题是动态规划中比较常见的问题之一,特别是在算法竞赛中。

一般来说,背包问题可分为两大类:01背包和完全背包。01背包是每个物品只能用一次,而完全背包则是每个物品可以无限制使用。

这里将介绍多种背包问题的分析和具体实现。

01背包问题

问题描述

有一个容量为V的背包和N个物品,每个物品的体积为v[i],价值为w[i],求在装满背包的前提下,最大化能够获得的总价值。

分析与实现

01背包问题采用二维数组dp[i][j]记录放置前i个物品,总体积不超过j时的最大价值。

具体地,依次枚举物品i和容量j(即i和j的范围分别为[1, N] 和[1, V] ),讨论第i个物品是否放入背包中:

  1. 若第i个物品的体积大于j,则不放入,此时dp[i][j]的值应该和dp[i-1][j]相同;
  2. 若第i个物品的体积小于等于j,则可以将其放入背包中,此时dp[i][j]应该等于dp[i-1][j-v[i]] + w[i];
  3. 比较第1步和第2步中两种情况所对应的dp值,选择其中较大的值即可。

下面是C语言的实现代码:

#include <stdio.h>
#include <string.h>

#define maxn 1005

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

int main() {
    int N, V;
    int v[maxn], w[maxn];
    int dp[maxn][maxn];

    scanf("%d%d", &N, &V);

    for (int i = 1; i <= N; i++)
        scanf("%d%d", &v[i], &w[i]);

    memset(dp, 0, sizeof(dp));

    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= V; j++) {
            if (j < v[i])
                dp[i][j] = dp[i - 1][j];
            else
                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - v[i]] + w[i]);
        }
    }

    printf("%d\n", dp[N][V]);

    return 0;
}

完全背包问题

问题描述

有一个容量为V的背包和N个物品,每个物品的体积为v[i],价值为w[i],每种物品都有无限个。在装满背包的前提下,最大化能够获得的总价值。

分析与实现

完全背包问题的dp数组和01背包问题一样是二维数组,但转移方程有所不同。

对于每个物品i,依次枚举背包中放入第i个物品的数目(即可能的xi,范围为[0, V/v[i]]),讨论第i个物品所能带来的价值:

  1. 若不放入第i个物品,则dp[i][j]的值应直接等于dp[i-1][j]。
  2. 若放入x个第i个物品,则dp[i][j]等于dp[i][j-xv[i]] + xw[i](这里借用前面提到的完全背包思想,将此方程写成这样)。

由此可得dp转移方程为:

dp[i][j] = max(dp[i-1][j], dp[i][j-v[i]] + w[i])

下面是C语言的实现代码:

#include <stdio.h>
#include <string.h>

#define maxn 1005

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

int main() {
    int N, V;
    int v[maxn], w[maxn];
    int dp[maxn][maxn];

    scanf("%d%d", &N, &V);

    for (int i = 1; i <= N; i++)
        scanf("%d%d", &v[i], &w[i]);

    memset(dp, 0, sizeof(dp));

    for (int i = 1; i <= N; i++) {
        for (int j = v[i]; j <= V; j++) {
            dp[i][j] = max(dp[i - 1][j], dp[i][j - v[i]] + w[i]);
        }
    }

    printf("%d\n", dp[N][V]);

    return 0;
}

示例说明

下面使用两个示例来说明上面介绍的两个问题。

示例1

输入:
4 5
1 2
2 4
3 4
4 5
输出:
9

解释:

这里有4个物品,容量为5,物品分别为1:(1,2),2:(2,4),3:(3,4),4:(4,5)。

使用01背包算法,可以得到最大价值为9,选择物品1和2。

示例2

输入:
4 5
1 2
2 4
3 4
4 5
输出:
10

解释:

这里与示例1相同,但与示例1不同的是,这里使用完全背包算法,最大价值为10,其中选择了物品2和4。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言动态规划多种背包问题分析讲解 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • C++如何调用简单的python程序

    当我们需要在C++应用程序中使用Python脚本时,可以使用Python的API来调用Python解释器,并通过API调用Python程序。下面是完整的攻略: 1. 准备工作 安装Python 首先,需要安装Python的开发环境。推荐使用Anaconda,我们可以从官网下载并安装,同时在安装过程中可以选择将Python添加到系统输入路径中。 配置环境变量 …

    C 2023年5月23日
    00
  • C++语言实现hash表详解及实例代码

    C++语言实现hash表详解及实例代码攻略 什么是哈希表? 哈希表(Hash Table),也叫散列表,是根据关键码值(Key Value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做哈希表。 哈希表的实现 哈希表的实现通常涉及以下三个部分: 哈希函数(Has…

    C 2023年5月24日
    00
  • Python实现利用最大公约数求三个正整数的最小公倍数示例

    下面为大家讲解一篇“Python实现利用最大公约数求三个正整数的最小公倍数”的攻略。 概述 我们需要使用Python语言来实现最小公倍数(LCM)的计算。但是,要计算LCM,首先需要计算最大公约数(GCD)。本教程介绍了计算三个正整数的LCM的方法,其中使用了最大公约数概念。 算法说明 计算三个数字的LCM的算法如下:1. 计算第一个数字和第二个数字的最大公…

    C 2023年5月22日
    00
  • C语言超全面讲解函数的使用方法下

    C语言超全面讲解函数的使用方法下 简介 函数是C语言中重要的组成部分,它可以将代码分解成小的模块,提高代码的可维护性,也可以提高代码的可重用性。在本攻略中,我们将全面讲解C语言中函数的使用方法,包括函数定义、函数调用、函数参数、函数返回值等方面。 函数定义 函数定义包括函数头和函数体两部分。函数头一般包括函数的返回值类型、函数名和函数参数。如下所示: int…

    C 2023年5月24日
    00
  • C语言分支循环其嵌套语句的使用

    对于C语言程序,分支和循环结构都是非常重要的控制结构。它们可以让程序根据条件执行不同的操作,并可以利用循环结构让重复的操作更加简单和高效。 在实际编程中,分支和循环结构的嵌套使用能够更好地解决实际问题。下面我们分别讲解分支和循环在嵌套结构中的使用方法。 分支结构的嵌套使用 分支结构通常使用if / else或switch / case语句完成。分支结构的嵌套…

    C 2023年5月30日
    00
  • C语言进阶之文件操作详解

    C语言进阶之文件操作详解 在C语言中,文件操作是一项非常重要的操作,涉及到了文件的创建、读写、修改、删除等各种操作。本文将针对文件操作的各个方面进行详细讲解。 文件的创建 在C语言中,文件的创建可以通过标准库函数 fopen() 来实现,其函数原型如下所示: FILE *fopen(const char *filename, const char *mode…

    C 2023年5月23日
    00
  • c/c++ 奇技淫巧(一些c语言的技巧)

    c/c++ 奇技淫巧(一些c语言的技巧) 1. 变量交换 有时我们需要交换两个变量的值,一般的做法是使用中间变量,但是有一个巧妙的方法可以不使用中间变量交换两个变量的值。 int a = 10, b = 5; a -= b; // a = 5 b += a; // b = 10 a = b – a; // a = 5 2. 求绝对值 结合位运算,可以使用以下…

    C 2023年5月23日
    00
  • Python JSON模块的使用详情

    Python JSON模块的使用详情 什么是JSON? JSON是JavaScript对象表示法(JavaScript Object Notation)的缩写,是一种轻量级的数据交换格式。它以易于阅读和编写的文本格式为基础,通常用于在网络之间传输数据。在Python中,有一个常用的模块叫做json,可以方便地对JSON数据进行编码和解码操作。 序列化与反序列…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部