【动态规划-背包模型part4(混合背包问题、背包问题方案数量)】:混合背包问题、机器分配、背包问题求方案数【已更新完成】

题目类型
混合背包问题混合背包问题
机器分配背包问题方案数量
背包问题求方案数背包问题方案数量

1、混合背包问题

有 N 种物品和一个容量是 V 的背包。

物品一共有三类:

第一类物品只能用1次(01背包); 第二类物品可以用无限次(完全背包); 第三类物品最多只能用 si 次(多重背包); 每种体积是 vi ,价值是 wi 。

求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。 输出最大价值。

输入格式
第一行两个整数,N,V ,用空格隔开,分别表示物品种数和背包容积。

接下来有 N 行,每行三个整数 vi,wi,si ,用空格隔开,分别表示第 i 种物品的体积、价值和数量。

si=−1 表示第 i 种物品只能用1次; si=0 表示第 i 种物品可以用无限次; si>0 表示第 i 种物品可以使用 si 次;
输出格式
输出一个整数,表示最大价值。

数据范围

0<N,V≤1000

0<vi,wi≤1000

−1≤si≤1000

输入样例
4 5
1 2 -1
2 4 1
3 4 0
4 5 2
输出样例:
8

思路:

完全背包问题可以转化为多重背包问题,这是本题的关键所在,完全背包能用无数次,等价于可以一种物品用到背包满为止,所以我们有/转化公式:

s[i]=m/v[i];

将完全背包转化为多重背包

另外,本题采用二进制优化来加快程序运行速度,二进制优化打包后就相当于01背包问题

代码:

#include<bits/stdc++.h>using namespace std;const int N=100010;int v[N],w[N],s[N];
int chmodv[N];
int chmodw[N];
int f[N];//将完全背包转化为多重背包(能取无数次相当于有背包体积/v个物品)
//-1 01 0 完全 >0 多重int n,m;//m是背包容积
int main()
{cin>>n>>m;for(int i=1;i<=n;i++){cin>>v[i]>>w[i]>>s[i];if(s[i]==-1)s[i]=1;//01背包转化为多重背包else if(s[i]==0)s[i]=m/v[i];//完全背包转化为多重背包}//二进制优化(朴素写法要三重循环,在第三重循环枚举s[i])//二进制优化后,多个物品被打包,相当于01背包问题//所以只需要01背包的做法(二重循环)int cnt=1;for(int i=1;i<=n;i++){int k=1;//用来二进制打包while(k<=s[i]){chmodv[cnt]=v[i]*k;chmodw[cnt]=w[i]*k;s[i]-=k;k*=2;cnt++;}if(s[i]>0){chmodv[cnt]=s[i]*v[i];chmodw[cnt]=s[i]*w[i];cnt++;}}///二进制优化完成//    朴素写法
//    for(int i=1;i<=cnt;i++)//这时候是多个物品打包在一起,做法和01背包一样
//    {
//        for(int j=0;j<=m;j++)
//        {
//            f[i][j]=f[i-1][j];
//            if(j>=chmodv[i])f[i][j]=max(f[i][j],f[i-1][j-chmodv[i]]+chmodw[i]);
//        }
//
//    }//  滚动数组写法(可以储存更多的状态,如果是二维存储的状态不够用)for(int i=1;i<=cnt;i++){for(int j=m;j>=chmodv[i];j--){f[j]=max(f[j],f[j-chmodv[i]]+chmodw[i]);}}cout<<f[m];return 0;
}

2、机器分配

总公司拥有 M 台 相同 的高效设备,准备分给下属的 N 个分公司。

各分公司若获得这些设备,可以为国家提供一定的盈利。盈利与分配的设备数量有关。

问:如何分配这M台设备才能使国家得到的盈利最大?

求出最大盈利值。

分配原则:每个公司有权获得任意数目的设备,但总台数不超过设备数 M 。

输入格式
第一行有两个数,第一个数是分公司数 N ,第二个数是设备台数 M ;

接下来是一个 N×M 的矩阵,矩阵中的第 i 行第 j 列的整数表示第 i 个公司分配 j 台机器时的盈利。

输出格式 第一行输出最大盈利值;

接下 N 行,每行有 2 个数,即分公司编号和该分公司获得设备台数。

答案不唯一,输出任意合法方案即可。

数据范围
1≤N≤10 , 1≤M≤15
输入样例:
3 3
30 40 50
20 30 50
20 25 30
输出样例:
70 1 1
2 1 3 1

思路:

每一个公司可以看作一个组,从每一组中选
最终用dfs寻找路径:!!从最终状态开始dfs!!倒推到初始状态

代码:

#include<bits/stdc++.h>using namespace std;const int N=12,M=17;int n,m;//公司数量和机器数量int g[N][M];int f[N][M];int path[N];
int cnt;void dfs(int i,int j)
{if(i==0)return ;for(int a=0;a<=j;a++){if(f[i-1][j-a]+g[i][a]==f[i][j]){path[cnt++]=a;dfs(i-1,j-a);return ;}}}int main()
{cin>>n>>m;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){scanf("%d",&g[i][j]);//读入数据矩阵}//每个公司可以看作一个组,从每一组中选for(int i=1;i<=n;i++)//从前i组里面选{for(int j=1;j<=m;j++)//枚举体积(总共m台机器){for(int k = 0;k <= j;k ++){f[i][j]=max(f[i][j],f[i-1][j]);f[i][j]=max(f[i][j],f[i-1][j-k]+g[i][k]);//g[i][k]可以解读为第i组中体积为k,价值为g[i][k]}}}cout<<f[n][m]<<endl;//find pathdfs(n,m);//因为是从最终状态开始find拓扑排序的//所以cnt==0的时候存储的是最终的状态//最终path要倒序输出for(int i=cnt-1,id=1;i>=0;id++,i--)cout<<id<<" "<<path[i]<<endl;
}

3、背包问题求方案数

有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。

第 i 件物品的体积是 vi ,价值是 wi 。

求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。

输出 最优选法的方案数。注意答案可能很大,请输出答案模 109+7 的结果。

输入格式
第一行两个整数,N,V ,用空格隔开,分别表示物品数量和背包容积。

接下来有 N 行,每行两个整数 vi,wi ,用空格隔开,分别表示第 i 件物品的体积和价值。

输出格式
输出一个整数,表示 方案数 模 109+7 的结果。

数据范围
0<N,V≤1000

0<vi,wi≤1000
输入样例
4 5
1 2
2 4
3 4
4 6
输出样例:
2

思路:

cnt[i]存储价值为i的时候的方案数
相当于进行两次dp

代码:

#include<bits/stdc++.h>using namespace std;//01背包问题求方案数
//f[i]存储体积为i的时候的最高价值
//cnt[i]存储体积为i的时候的最高价值(f[i])对应的方案数const int N=1003;int f[N];
int cnt[N];int v[N],w[N];int mod=1e9+7;int main()
{int n,m;cin>>n>>m;for(int i = 0; i <= m; i ++)  cnt[i] = 1;//初始值全部设置为1//因为最高价值都可以为0,方案就可以有一种for(int i=1;i<=n;i++){scanf("%d%d",&v[i],&w[i]);}for(int i=1;i<=n;i++)for(int j=m;j>=v[i];j--){int value=f[j-v[i]]+w[i];if(value>f[j])//找到价值更高的方案{f[j]=value;cnt[j]=cnt[j-v[i]];}else if(value==f[j]){cnt[j]=(cnt[j]+cnt[j-v[i]])%mod;}}cout<<cnt[m];return 0;
}

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

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

相关文章

Ora-32004错误处理

问题现象 处理方法 观察alert会发现报错的参数在加载spfile的阶段 按照mos的方法对其reset 重新启动无报错 观察日志无报错

六(2)、RTKLIB源码解析 — postpos.c

目录 一、主要流程 二、主体代码 三、主要调用函数解析 3.1 openses() 3.2 closeses() 3.3

Unity学习笔记---资源管理

素材存放 Resources目录 在Assets的任何子目录下创建Resources目录&#xff0c;Unity会自动检索到这些目录并使用。该目录主要用于加载资源&#xff0c;将需要加载的资源放在该目录下。 该目录的内容大小不能超过2G TextAsset类 ScriptableObject类 AssetDatabase类 Pla…

c++多线程异常

在C中&#xff0c;捕获线程抛出的异常需要特别注意&#xff0c;因为默认情况下&#xff0c;如果一个线程抛出异常并且没有被捕获&#xff0c;整个程序可能会终止。为了安全地捕获和处理线程中的异常&#xff0c;可以考虑以下方法&#xff1a; 方法一&#xff1a;在线程函数中使…

ora-00392 ora-00312错误处理

检查当前日志组状态 对日志组进行clear操作 重新开库无报错

java的变量关系~使用和扩展

一、变量的概述 1、什么是变量 白话:变量就是一个装东西的盒子。 通俗:变量是用于存放数据的容器。我们通过变量名 获取数据&#xff0c;甚至数据可以修改。 2、变量在内存中的存储 本质:变量是程序在内存中申请的一块用来存放数据的空间&#xff0c;类似我们酒店的房间&a…

Spring Bean的“魔法”之旅:深入剖析属性填充的艺术

1. 引言 在Spring框架中&#xff0c;Bean的生命周期是一个复杂而精妙的过程&#xff0c;而属性填充&#xff08;Property Population&#xff09;作为这一过程中的关键阶段&#xff0c;对于Bean的初始化和功能实现至关重要。为了更生动地展示Spring Bean属性填充的机制&#x…

C++ (week5):Linux系统编程3:线程

文章目录 三、线程1.线程的基本概念①线程相关概念②我的理解 2.线程的基本操作 (API)(1)获取线程的标识&#xff1a;pthread_self(2)创建线程&#xff1a;pthread_create()(3)终止线程①pthread_exit()&#xff1a;当前线程终止&#xff0c;子线程主动退出②pthread_cancel()&…

OrangePi AIpro(8T) 基本介绍和资料汇总

OrangePi AIpro 基本介绍和资料汇总 1 介绍1.1 香橙派(Orange Pi) 公司概述1.2 OrangePi AIpro(8T) 介绍概述硬件规格参数引脚图产品详细图芯片优缺点优点 2 资料汇总2.1 官方资料概述资料下载 参考 1 介绍 1.1 香橙派(Orange Pi) 公司概述 香橙派&#xff08;Orange Pi&…

惊喜:我一晚上赚了10万!深扒挖瑞幸1.8亿起死回生的商业真相

■ ■ ■ ■ 瑞幸咖啡 2020年1月&#xff0c;浑水报告发出后&#xff0c;瑞幸股价一路颠簸&#xff0c;最终退市停牌。 然而&#xff0c;19个月后&#xff0c;在粉单市场股价再次增长781.16% 暴雷后的19个月&#xff0c;瑞幸经历了怎样的起死回生&#xff1f; 2020年4月2日…

掌握SQL注入检测:深入理解SQLMAP工具

引言 在网络安全领域&#xff0c;SQL注入是一个广泛存在的漏洞&#xff0c;它允许攻击者通过Web应用对数据库执行非法的SQL命令。SQLMAP是检测这类漏洞的顶尖工具之一。本文将深入探讨SQLMAP工具&#xff0c;从其基本介绍到高级使用技巧&#xff0c;帮助读者全面理解并有效运用…

如何让线程安全的List

如何让线程安全的List Collections.synchronizedList 首先是用Collections.synchronizedList方法可以把普通的List转为线程的安全List。所有对该List的访问都会被同步 import java.util.Collections; import java.util.List; import java.util.ArrayList;public class Threa…

【RuoYi】如何启动RuoYi项目

一、前言 最近&#xff0c;在做一个管理系统的项目&#xff0c;接触到了RuoYi这个前后端分离的框架&#xff0c;自己是第一次接触这个框架&#xff0c;所以刚开始有点好奇&#xff0c;在用该框架写了一些代码后。发现RuoYi这个框架做的真的好&#xff0c;它包含了权限管理和一些…

网红郭有才是怎么火起来的

网红郭有才的爆火主要归因于以下几个因素&#xff1a; 独特的个人魅力与风格&#xff1a;郭有才以其地道的乡土气息和个人的朴实无华赢得了观众的喜爱。他的视频内容展现了真实且接地气的生活场景&#xff0c;给人以亲切感。同时&#xff0c;他的幽默感也是吸引观众的一个重要因…

【稳定检索】2024年电子技术、传感器与信号处理国际会议(ETSS 2024)

2024年电子技术、传感器与信号处理国际会议 2024 International Conference on Electronic Technology, Sensors, and Signal Processing 【1】会议简介 2024年电子技术、传感器与信号处理国际会议&#xff0c;作为业内领先的学术交流平台&#xff0c;将汇聚全球顶尖的电子技术…

99%的人都不知道,微信才是真正的学习神器

微信&#xff0c;作为一款全球最受欢迎的社交应用之一&#xff0c;除了聊天、朋友圈、小程序等功能外&#xff0c;还有许多隐藏的学习功能&#xff0c;今天小编就给大家分享10个微信隐藏的学习功能&#xff0c;助您轻松成为学霸。 1、微信笔记 用过代办清单软件的朋友都知道&…

如何调用通义千问大模型API

目录 登录阿里云 大模型服务平台百炼 登录控制台 QWen Long QWen 通义千问开源系列 大语言模型 OpenAI接口兼容 登录阿里云 阿里云-计算&#xff0c;为了无法计算的价值 大模型服务平台百炼 降价信息&#xff1a; 登录控制台 右上角取得API key 创建Key QWen Long qw…

Linux网络编程:传输层协议|UDP

知识引入&#xff1a; 端口号&#xff1a; 当应用层获得一个传输过来的报文时&#xff0c;这时数据包需要知道&#xff0c;自己应该送往哪一个应用层的服务&#xff0c;这时就引入了“端口号”&#xff0c;通过区分同一台主机不同应用程序的端口号&#xff0c;来保证数据传输…

【VTKExamples::Utilities】第九期 FrameRate

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享VTK样例FrameRate,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO 1. FrameRate 该样例介绍 如…

「架构」云上自动化运维及其应用

随着云计算的普及,自动化运维成为企业提升运营效率和降低成本的关键。本文通过分析一家中型企业实施云上自动化运维(CloudOps)的案例,探讨了自动化监控、配置管理和持续集成/持续部署(CI/CD)三个核心模块的实际应用。文章详细阐述了每个模块的技术选型、实施原因、优缺点…