动态规划——机器分配、01背包问题

 一、机器分配 

题目名称:机器分配 
题目描述:
总公司拥有高效设备M台,准备分给下属的N个分公司。
各分公司若获得这些设备,可以为国家提供一定的盈利。
问:如何分配这M台设备才能使国家得到的盈利最大?求出最大盈利值。
其中M≤100,N≤100。
分配原则:每个公司有权获得任意数目的设备,但总台数不超过设备数M。

输入输出格式

输入格式:
第一行有两个数,第一个数是分公司数N,第二个数是设备台数M;
接下来是一个N*M的矩阵,表明了第 I 个公司分配 J 台机器的盈利。

输出格式:
第一行输出最大盈利值; 接下N行,每行有2个数,即分公司编号和该分公司获得设备台数。

(一)解题思路

1. 问题定义

总公司有n个分公司,现在有m台设备可以分配给这些分公司。每个分公司i如果得到j台设备,会产生一定的盈利a[i][j]。任务是找到一个分配方案,使得所有分公司获得的盈利总和最大。

2. 动态规划的基本思想

动态规划是一种通过把原问题分解为相对简单的子问题的方式来求解复杂问题的方法。它通常用于优化问题,比如求最大值或最小值。在这个问题中,我们使用动态规划来找到最大的盈利总和。

3. 状态定义

我们定义一个二维数组f,其中f[i][j]表示前i个分公司分配j台设备时的最大盈利。注意,这里我们是从1开始索引的,所以f[1][0]表示第一个分公司没有分配到设备时的盈利(通常是0,因为没有设备就没有盈利)。

4. 状态转移方程

对于每个分公司i和每个可能的设备数量j,我们需要考虑把k台设备(其中0 <= k <= j)分配给分公司i,然后看看这样分配是否会比之前的分配方案产生更多的盈利。我们可以使用以下状态转移方程来更新f[i][j]

f[i][j] = max(f[i][j], f[i-1][j-k] + a[i][k])

这里,f[i-1][j-k]表示前i-1个分公司分配j-k台设备时的最大盈利,a[i][k]表示第i个分公司分配k台设备时的盈利。我们通过遍历所有可能的k值来找到使f[i][j]最大的那个。

5. 记录路径

为了能够在找到最大盈利后回溯出具体的设备分配方案,我们需要一个额外的二维数组res来记录每个状态f[i][j]是如何达到的。具体来说,res[i][j]应该存储分配给分公司i的设备数量k,这个k是在计算f[i][j]时使盈利最大的那个。

6. 初始化

我们需要初始化f数组和res数组。通常,我们会把f数组的所有元素初始化为一个很小的值(表示还没有计算过),然后把f[0][0]初始化为0(表示没有分公司和没有设备时的盈利为0)。在这个问题中,由于盈利是非负的,并且我们总是试图最大化盈利,所以我们可以简单地把f数组的所有元素(除了f[0][0])看作是未初始化的,然后在计算过程中更新它们。res数组也需要初始化,但在这个问题中,我们只需要在更新f[i][j]的同时也更新res[i][j]即可。

7. 回溯

一旦我们计算出了f[n][m](即所有分公司分配所有设备时的最大盈利),我们就可以使用res数组来回溯出具体的设备分配方案。我们从f[n][m]开始,根据res[n][m]找到分配给最后一个分公司的设备数量,然后递归地找到分配给前面分公司的设备数量,直到我们回溯到f[1][0](或实际上是我们开始回溯的第一个有效状态)。

(二)代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstdlib>
#include <queue>
#include <vector>
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define N 30
#define MOD 2520
#define E 1e-12
using namespace std;int a[N][N], f[N][N], res[N][N]; void print(int x, int y) {if (x == 0)return;print(x - 1, y - res[x][y]);printf("%d %d\n", x, res[x][y]);
}int main() {int n, m;cin >> n >> m; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) cin >> a[i][j];for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) for (int k = 0; k <= j; k++) if (f[i][j] <= f[i-1][j-k] + a[i][k]) {f[i][j] = f[i-1][j-k] + a[i][k];res[i][j] = k; }// 输出结果cout << f[n][m] << endl;print(n,m);return 0;
}

二、01背包问题

描述

一个旅行者有一个最多能装 M 公斤的背包,现在有 n 件物品,它们的重量分别是W1,W2,…,Wn,它们的价值分别为C1,C2,…,Cn,求旅行者能获得最大总价值。

输入格式

第一行:两个整数,M(背包容量,M≤200)和N(物品数量,N≤30);
第2至N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。

输出格式

仅一行,一个数,表示最大总价值。

样例

输入样例

10 4
2 1
3 3
4 5
7 9

输出样例

12

(一)解题思路

  1. 问题定义与数据输入
    (1)我们需要明确背包的容量m和物品的数量n
    (2)输入每个物品的体积v[i]和价值w[i](其中i代表物品编号)。
  2. 动态规划数组的初始化
    (1)定义一个二维数组f[i][j],其中i代表物品编号(从1到n),j代表当前的背包容量(从0到m)。
    (2)f[i][j]表示当只考虑前i个物品,且背包容量为j时,能够获得的最大价值。
    (3)初始化f[0][j]为0,表示当没有物品可选时,任何背包容量下的最大价值都是0。
  3. 状态转移方程
    (1)对于每个物品i和每个可能的背包容量j,我们需要决定是否将该物品放入背包中。
    (2)如果不放入物品i,则f[i][j] = f[i-1][j],即当前最大价值等于前i-1个物品在背包容量为j时的最大价值。
    (3)如果放入物品i,则f[i][j] = f[i-1][j-v[i]] + w[i],但前提是背包容量j必须大于等于物品i的体积v[i]
    (4)因此,状态转移方程为:

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

    f[i][j] = f[i-1][j]  当j<v[i]时

(二)代码

#include <iostream>
using namespace std;const int N = 210;
int n, m; // n表示物体个数,m表示背包容量
int v[N], w[N]; // v[i]表示第i个物品的体积,w[i]表示第i个物品的价值
int f[N][N]; // f[i][j]表示前i个物品在总体积不超过j时的最大价值int main() {cin >> m >> n; // m表示背包容量,n表示物体个数for (int i = 1; i <= n; i++) {cin >> v[i] >> w[i]; // 读入每个物品的体积和价值}// 初始化f数组,f[0][j]表示没有物品可选时,任何体积下的最大价值都是0for (int j = 0; j <= m; j++) {f[0][j] = 0;}// 动态规划求解背包问题for (int i = 1; i <= n; i++) { // 表示只选择前i个物体for (int j = 1; j <= m; j++) { // 表示体积f[i][j] = f[i - 1][j]; // 如果不选第i个物品,则价值等于前i-1个物品在体积j下的最大价值if (j >= v[i]) { // 如果体积允许选择第i个物品f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]); // 选择第i个物品,并更新最大价值}}}// 输出结果,表示选择前n个物品,体积为m时的最大价值cout << f[n][m] << endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/63643.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入解析 JavaScript 中的 Blob 对象:二进制数据处理的核心

文章目录 1.Blob是什么2.Blob用法实例属性Blob方法slice方法text方法 示例1&#xff1a;字符串 Blob示例2&#xff1a;数组和字符串 Blob示例3&#xff1a;从文件输入创建 3.使用场景1.创建 Blob 并生成 URL&#xff0c;下载文件2.文件上传3.切片上传3.Blob用于URL在线预览PDF文…

NanoLog起步笔记-7-log解压过程初探

nonolog起步笔记-6-log解压过程初探 再看解压过程建立调试工程修改makefile添加新的launch项 注&#xff1a;重新学习nanolog的README.mdPost-Execution Log Decompressor 下面我们尝试了解&#xff0c;解压的过程&#xff0c;是如何得到文件头部的meta信息的。 再看解压过程 …

人工智能大模型LLM开源资源汇总(持续更新)

说明 目前是大范围整理阶段&#xff0c;所以存在大量机翻说明&#xff0c;后续会逐渐补充和完善资料&#xff0c;减少机翻并增加说明。 Github上的汇总资源&#xff08;大部分英文&#xff09; awesome-production-machine-learning 此存储库包含一系列精选的优秀开源库&am…

C++实现排序算法:冒泡排序

目录 前言 冒泡排序性质 C代码实现冒泡排序 冒泡图解 第一趟排序 第二趟排序 第三趟排序 排序结果 结语 前言 冒泡排序的基本思想是通过从前往后&#xff08;从后往前&#xff09;两两比较&#xff0c;若为逆序&#xff08;即arr[i] < arr[i 1]&#xff09;则交换…

中介者模式的理解和实践

一、中介者模式概述 中介者模式&#xff08;Mediator Pattern&#xff09;&#xff0c;也称为调解者模式或调停者模式&#xff0c;是一种行为设计模式。它的核心思想是通过引入一个中介者对象来封装一系列对象之间的交互&#xff0c;使得这些对象不必直接相互作用&#xff0c;从…

PlantUML——类图

背景 类图是UML模型中的静态视图&#xff0c;其主要作用包括&#xff1a; 描述系统的结构化设计&#xff0c;显示出类、接口以及它们之间的静态结构和关系。简化对系统的理解&#xff0c;是系统分析与设计阶段的重要产物&#xff0c;也是系统编码和测试的重要模型依据。 在U…

【Java知识】Java进阶-如何开启远程调式

java远程调试 概述Java远程调试的开启与底层原理开启Java远程调试底层原理 JVM参数 概述 Java远程调试的开启与底层原理 开启Java远程调试 Java远程调试允许开发者在本地IDE&#xff08;如Eclipse、IntelliJ IDEA等&#xff09;中调试运行在远程服务器上的Java应用程序。以下…

入选国家数据局案例!浙江“一体化智能化公共数据平台”总体架构详解~

国家数据局在2024中国国际大数据产业博览会上发布了首批50个数字中国建设典型案例。案例涉及数据基础设施、数据资源、数字技术创新、数字政府、数字经济、数字社会、数字文化、数字生态文明等领域&#xff0c;集中反映了近年来数字中国建设的实践和成效。 其中&#xff0c;由…

vscode IntelliSense Configurations

IntelliSense 是一个强大的代码补全和代码分析功能&#xff0c;它可以帮助开发者提高编程效率。图中显示的是 VSCode 的 IntelliSense 配置界面&#xff0c;具体配置如下&#xff1a; Compiler path&#xff08;编译器路径&#xff09;: 这里指定了用于构建项目的编译器的完整路…

同三维TL200H2S6 6机位精品教育录播主机

录制点播、直播导播、互动、音频处理器、中控等多功能为一体 8路视频输入:6路SDI1路HDMI1(4K30)1路(3选1:HDMI2/2路VGA) 2路视频输出&#xff1a;1路HDMI1(4K30)1路&#…

欢乐斗地主案例

1&#xff0c;创建对象 package anlidoudizhu;public class pai implements Comparable<pai> {private Double value;private String name;Overridepublic int compareTo(pai o) {return -Double.compare(this.value,o.value);}//升序排序&#xff0c;treeset集合public…

技术型企业如何高效搭建企业博客以增强品牌影响力和市场竞争力

在数字化时代&#xff0c;技术型企业面临着激烈的市场竞争和快速变化的行业环境。为了在这场竞争中脱颖而出&#xff0c;企业需要寻找新的营销渠道和品牌建设工具。企业博客作为一种低成本、高效率的在线内容平台&#xff0c;已经成为技术型企业增强品牌影响力和市场竞争力的重…

go-zero(十二)消息队列

go zero 消息队列 在微服务架构中&#xff0c;消息队列主要通过异步通信实现服务间的解耦&#xff0c;使得各个服务可以独立发展和扩展。 go-zero中使用的队列组件go-queue&#xff0c;是gozero官方实现的基于Kafka和Beanstalkd 的消息队列框架,我们使用kafka作为演示。 一、…

【JAVA高级篇教学】第二篇:使用 Redisson 实现高效限流机制

在高并发系统中&#xff0c;限流是一项非常重要的技术手段&#xff0c;用于保护后端服务&#xff0c;防止因流量过大导致系统崩溃。本文将详细介绍如何使用 Redisson 提供的 RRateLimiter 实现分布式限流&#xff0c;以及其原理、使用场景和完整代码示例。 目录 一、什么是限流…

基于卷积神经网络的Caser算法

将一段交互序列嵌入到一个以时间为纵轴的平面空间中形成“一张图”后&#xff0c;基于卷积序列嵌入的推荐&#xff08;Caser&#xff09;算法利用多个不同大小的卷积滤波器&#xff0c;来捕捉序列中物品间的点级&#xff08;point-level&#xff09;、联合的&#xff08;union-…

ubuntu下的chattts 学习5:Example: self introduction

代码 import ChatTTS import torch import torchaudiochat ChatTTS.Chat() chat.load(compileFalse) # Set to True for better performance ################################### inputs_en """ chat T T S is a text to speech model designed for dialogu…

【银河麒麟高级服务器操作系统】修改容器中journal服务日志存储位置无效—分析及解决方案

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://documentkylinos.cn 服务器环境以及配置 【机型】 整机类型/架构&am…

HTML:表格重点

用表格就用table caption为该表上部信息&#xff0c;用来说明表的作用 thead为表头主要信息&#xff0c;效果加粗 tbody为表格中的主体内容 tr是 table row 表格的行 td是table data th是table heading表格标题 &#xff0c;一般表格第一行的数据都是table heading

[创业之路-187]:《华为战略管理法-DSTE实战体系》-1-从UTStarcom的发展历程,如何辩证的看企业初期发展太顺利中的危机

目录 一、UTStarcom&#xff08;UT斯达康&#xff09;的发展历程 1、创立与初期发展 2、快速成长与上市 3、技术创新与业务拓展 4、战略调整与持续发展 二、从UTStarcom的发展历程&#xff0c;如何辩证的看企业初期发展太顺利中的危机 1、企业初期发展的顺利表现 2、顺…

ubuntu系统生成SSL证书配置https

自签名【Lets Encrypt】的测试证书&#xff0c;有效期三个月。 第一步&#xff1a;安装acme&#xff0c;如果没有安装git&#xff0c;需要提前安装 下载came资源 git clone https://github.com/Neilpang/acme.sh.git 无法访问&#xff0c;可以试用gitee的资源&#xff0c;安…