动态规划--重拾我的“背包”

前言:

  背包问题所涉及的是经典的动态规划算法。因为长时间不AC了,渐渐感觉思维也都麻了!本文将基础的背包问题做个小结,方便以后翻阅。感兴趣的朋友也可以阅读一下~
------------------------
(1)如何从n个重量和价值分别为Vi、Wi的物品中选择一或多个放入最大容纳量为S的背包使其总价值最大?

输入:

5 10   (分别表示:n,S)
2 3
7 5
3 1
5 10
2 2

5 6
2 3
7 5
3 1
5 10
2 2

输出:

15

10

分析:
f[i][j]:表示背包在存放了前i件物品占据j重量时的价值
其中,1<=i<=n,0<=j<=S;

当我到达某一个状态,需要选择是否将第i件物品放入我的背包时,必须考虑值不值的问题,即:
f[i][j] = max(f[i-1][j],f[i-1]][j-w[i]]+v[i]);

理解了上面的状态转移方程之后,就可以方便得出下面的伪代码了:

  f[0...n][0...S] <- 0 //初始化
  for i<-1:n
    for j<-w[i]:S
      f[i][j] = max(f[i-1][j],f[i-1]][j-w[i]]+v[i]); //状态转移

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int maxn=1e3+10;
 6 int f[maxn][maxn];
 7 int main(){
 8     //数据从文件读入
 9     freopen("datain.txt","r",stdin);
10     int n,S,a,b;
11     while(scanf("%d%d",&n,&S)==2){
12         memset(f,0,sizeof(f));
13         for(int i=1;i<=n;i++){
14             scanf("%d%d",&a,&b);
15             for(int v=1;v<=S;v++){
16                 if(v>=a)        //do not neglect 'v<a'
17                     f[i][v] = max(f[i-1][v],f[i-1][v-a]+b);
18                 else
19                     f[i][v] = f[i-1][v];
20             }
21         }
22         printf("%d\n",f[n][S]);
23     }
24     return 0;
25 }

以上算法的时间复杂度、空间复杂度均为:O(n*S)

f[i][j]的变化过程:

-----------------------------

|   0 3 3 3 3 3 3 3 3 3           |

|   0 3 3 3 3 3 5 5 8 8           |
|   0 3 3 3 4 4 5 5 8 8           |  
|   0 3 3 3 10 10 13 13 13 14 |
|   0 3 3 5 10 10 13 13 15 15 |

-----------------------------

 

在深入理解了状态转移方程之后,我们其实还可以对空间进行优化,仅用f[i]表示:背包质量达到i是获得的价值。对应的伪代码如下:

  f[0...S]<-0
  for i<-1:n
    for j<-S:w[i] //从右往左更新!
      f[j] = max(f[j],f[j-w[i]]+v[i]);

对空间进行优化后的代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int maxn=1e3+10;
 6 int f[maxn];
 7 int main(){
 8     freopen("datain.txt","r",stdin);
 9     int n,S,a,b;
10     while(scanf("%d%d",&n,&S)==2){
11         memset(f,0,sizeof(f));
12         for(int i=0;i<n;i++){
13             scanf("%d%d",&a,&b);
14             for(int v=S;v>=a;v--){
15                 f[v] = max(f[v],f[v-a]+b);
16             }
17         }
18         printf("%d\n",f[S]);
19     }
20     return 0;
21 }

 

(2)如何从n个重量和价值分别为Vi、Wi的物品中选择一或多个放入最大容纳量为S的背包在背包刚好装满情况下,使其总价值最大?

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int maxn=1e3+10;
 6 int f[maxn];
 7 int main(){
 8     freopen("datain.txt","r",stdin);
 9     int n,S,a,b;
10     while(scanf("%d%d",&n,&S)==2){
11         for(int i=1;i<=S;i++) f[i]=-0xfffffff;   //最小的int
12         f[0]=0;
13         for(int i=0;i<n;i++){
14             scanf("%d%d",&a,&b);
15             for(int v=S;v>=a;v--){
16                 f[v] = max(f[v],f[v-a]+b);
17             }
18         }
19         printf("%d\n",f[S]);
20     }
21     return 0;
22 }
View Code

输入:

5 10   (分别表示:n,S)
2 3
7 5
3 1
5 10
2 2

输出:14

(3)如何从n种(每种无限个)重量和价值分别为Vi、Wi的物品中选择一或多个放入最大容纳量为S的背包使其总价值最大?

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int maxn=1e3+10;
 6 int f[maxn];
 7 int main(){
 8     freopen("datain.txt","r",stdin);
 9     int n,S,a,b;
10     while(scanf("%d%d",&n,&S)==2){
11         memset(f,0,sizeof(f));
12         for(int i=0;i<n;i++){
13             scanf("%d%d",&a,&b);
14             for(int v=a;v<=S;v++){
15                 f[v] = max(f[v],f[v-a]+b);
16             }
17         }
18         printf("%d\n",f[S]);
19     }
20     return 0;
21 }
View Code

输入:

5 6
2 3
7 5
3 1
5 10
2 2

输出:10

(4)如何从n种(每种无限个)重量和价值分别为Vi、Wi的物品中选择一或多个放入最大容纳量为S的背包在背包刚好装满情况下,使其总价值最大?

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int maxn=1e3+10;
 6 int f[maxn];
 7 int main(){
 8     freopen("datain.txt","r",stdin);
 9     int n,S,a,b;
10     while(scanf("%d%d",&n,&S)==2){
11         for(int i=0;i<=S;i++) f[i]=-0xfffffff;
12         f[0]=0;
13         for(int i=0;i<n;i++){
14             scanf("%d%d",&a,&b);
15             for(int v=a;v<=S;v++){
16                 f[v] = max(f[v],f[v-a]+b);
17             }
18         }
19         printf("%d\n",f[S]);
20     }
21     return 0;
22 }
View Code

输入:

5 6
2 3
7 5
3 1
5 10
2 2

输出:9

----------------------------------------------
结语:
本文限于篇幅就只是对最最基本的01背包问题作了个人的分析,后面的3个扩展只贴代码,希望感兴趣的朋友们可以旁击侧敲吧~有问题或独特见解的博友请留言~

转载于:https://www.cnblogs.com/SeaSky0606/p/4743758.html

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

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

相关文章

Java 8 SE可选,严格的方法

大约两周前&#xff0c;Stephen Colebourne提出了使用Optional的实用方法 。 如果您阅读了它&#xff0c;您可能会从我以前的建议中猜到我不同意。 总览 我必须以免责声明开头&#xff0c;但随后我将直接解释为什么我认为他的方法不够理想。 所有不归因于他人的报价均摘自Ste…

routersploit简单实例

https://github.com/reverse-shell/routersploit RouterSploit。它包含了27个品牌的上百种漏洞利用模块&#xff0c;涉及的路由器、摄像头等设备有几百种。渗透的时候&#xff0c;用户首先根据目标设备的品牌选择对应的扫描模块&#xff0c;用以发现漏洞。一旦漏洞识别&#x…

《Spring3.0就这么简单》

第一章 认识Spring 1、Spring提供的IOC容器&#xff0c;是Spring大杀器之一。容器将对象之间的依赖关系交给Spring进行控制&#xff0c;采用配制的方式对依赖关系进行描述&#xff0c;由Ioc容器负责依赖类之间的创建、拼接、管理、获取工作 2、Spring提供的第二大杀器&#xff…

前端面试题之http/HTML/浏览器(一)

1.cookie sessionStorage localStorage区别&#xff1f;答&#xff1a;cookie数据始终在同源的http请求中携带(即使不需要)&#xff0c;即cookie在浏览器和服务器间来回传递cookie数据还有路径&#xff08;path&#xff09;的概念&#xff0c;可以限制。cookie只属于某个路径下…

[Vulhub](WooYun-2016-199433)phpmyadmin反序列化漏洞

0x00 预备知识 什么是序列化 序列化 (serialize)是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间&#xff0c;对象将其当前状态写入到临时或持久性存储区。以后&#xff0c;可以通过从存储区中读取或反序列化对象的状态&#xff0c;重新创建该对象。【将状…

用户指南接口

在AppDelegate在代码 视图控制器里的 版权声明&#xff1a;本文博客原创文章。博客&#xff0c;未经同意&#xff0c;不得转载。 转载于:https://www.cnblogs.com/bhlsheji/p/4747547.html

前端面试题之http/HTML/浏览器(二)

csrf和xss的网络攻击及防范&#xff1f;答&#xff1a;CSRF&#xff1a;跨站请求伪造&#xff0c;可以理解为攻击者盗用了用户的身份&#xff0c;以用户的名义发送了恶意请求&#xff0c;比如用户登录了一个网站后&#xff0c;立刻在另一个&#xff54;&#xff41;&#xff42…

查看目标主机安装的杀毒软件

命令&#xff1a; wmic /namespace:\\root\securitycenter2 path antivirusproduct GET displayName,productState, pathToSignedProductExe 参考链接&#xff1a;https://stackoverflow.com/questions/42472336/is-there-a-command-to-check-if-there-was-any-antivirus-insta…

Netty系列之Netty百万级推送服务设计要点

原文&#xff1a;http://www.infoq.com/cn/articles/netty-million-level-push-service-design-points 1. 背景 1.1. 话题来源 最近很多从事移动互联网和物联网开发的同学给我发邮件或者微博私信我&#xff0c;咨询推送服务相关的问题。问题五花八门&#xff0c;在帮助大家答疑…

上架APPStore需要准备哪些材料?

前端时间用敏捷式开发平台开发了一款APP应用&#xff0c;应用名称我就不说啦&#xff0c;这篇文章主要讲述一下上架苹果应用商店APPStore需要准备哪些材料&#xff0c;有相关的困扰欢迎私信我。一、上架流程1. 注册苹果企业账号2. 创建测试证书&#xff0c;发布证书 (使用Mac)3…

浅谈C++设计模式之工厂方法(Factory Method)

为什么要用设计模式&#xff1f;根本原因是为了代码复用&#xff0c;增加可维护性。 面向对象设计坚持的原则&#xff1a;开闭原则&#xff08;Open Closed Principle&#xff0c;OCP&#xff09;、里氏代换原则&#xff08;Liskov Substitution Principle&#xff0c;LSP&…

上架Android应用到腾讯应用包、百度手机助手、华为应用市场、小米应用商店、阿里应用分发平台需要准备哪些材料?...

前端时间用敏捷式开发平台开发了一款APP应用&#xff0c;应用名称我就不说啦&#xff0c;这篇文章主要讲述一下上架各大安卓应用商店&#xff08;腾讯应用宝、阿里应用商店、百度手机助手、华为应用市场、小米应用商店&#xff09;需要准备哪些材料&#xff0c;有相关的困扰欢迎…

【APICloud系列|18】上架Android应用到腾讯应用包、百度手机助手、华为应用市场、小米应用商店、阿里应用分发平台需要准备哪些材料?

前端时间用敏捷式开发平台开发了一款APP应用,应用名称我就不说啦,这篇文章主要讲述一下上架各大安卓应用商店(腾讯应用宝、阿里应用商店、百度手机助手、华为应用市场、小米应用商店)需要准备哪些材料,有相关的困扰欢迎私信我。 一、应用商店选择 推荐平台(六选五) 1.…

Activiti 6中的可插拔持久性

在过去的几年中&#xff0c;我们经常听到&#xff08;来自社区和我们的客户&#xff09;关于如何将Activiti的持久性逻辑从关系数据库交换到其他内容的请求。 当我们宣布Activiti 6时&#xff0c; 我们做出的承诺之一就是我们将实现这一目标。 深入研究Activiti引擎代码的人会…

src漏洞类型总结

本文转载于https://blog.csdn.net/qq_33942040/article/details/111831536 这三类存在漏洞可能更大 越他娘丑的站&#xff0c;越有可能存在洞。 Asp aspx 存在漏洞的可能更大 登陆口没得验证码的可能存在一,未授权访问 常见28种服务器或者中间协议未授权访问 易出现处 ①照片…

【APICloud系列|19】上架APPStore需要准备哪些材料?

前端时间用敏捷式开发平台开发了一款APP应用,应用名称我就不说啦,这篇文章主要讲述一下上架苹果应用商店APPStore需要准备哪些材料,有相关的困扰欢迎私信我。 一、上架流程 1. 注册苹果企业账号 2. 创建测试证书,发布证书 (使用Mac) 3. 使用xcode 上传应用到APP Store (…

Json注入

一、Json简介 JSON 是存储和交换文本信息的语法&#xff0c;是轻量级的文本数据交换格式。类似xml&#xff0c;但JSON 比 XML 更小、更快&#xff0c;更易解析。所以现在接口数据传输都采用json方式进行。JSON 文本的 MIME 类型是 “application/json”。 json语法 数据在名…

国行 lg g3 D858 刷 lg g3 D858hk 教程(备忘)

纯手打&#xff0c;转载请注明出处~ 刷机有风险&#xff0c;出现问题概不负责&#xff01; 本着自娱自乐的宗旨 &#xff0c;分享一下&#xff0c;出了问题不负责&#xff01; 准备的材料&#xff1a; 1&#xff0c;手机一枚&#xff08;废话&#xff09;国行lg g3 d858 2&am…

渗透测试-验证码的爆破与绕过

【验证码机制原理】 客户端发起请求->服务端响应并创建一个新的SessionID同时生成随机验证码&#xff0c;将验证码和SessionID一并返回给客户端->客户端提交验证码连同SessionID给服务端->服务端验证验证码同时销毁当前会话&#xff0c;返回给客户端结果。 【客户端可…

最近对项目代码做的一些更改和感想

最近对项目代码做了一些更改&#xff0c;主要的改动是对整个界面框架的改变&#xff0c;因为以前写代码的时候&#xff0c;为了完成功能&#xff0c;没有从上帝视角来思考软件的界面设计&#xff0c;完全是需要这个功能了&#xff0c;怎么可以做到&#xff1f;好&#xff0c;就…