完美世界2016实习生招聘编程题-小萌的包裹
来源:互联网 发布:it行业是什么意思 编辑:程序博客网 时间:2024/05/01 01:46
最近在牛客网上刷题,其中完美世界的实习生招聘的一道编程题觉得很有意思,就贴出来和大家分享!!!题目是这样的:
看到这个题想到的是贪心算法,但是后来想想觉得不对(在贪心算法中,物品放入背包的顺序不是物品的排列顺序,而是按照一定的条件进行,比如按价值量/体积的商的大小装入,使得背包的总价值量最大等等)。但是这个题主要有以下特点:
(1).一旦不往一个包里放物品,这个背包的口将封住不再使用。假设有小萌有两个背包,编号为1和2。一旦小萌决定往第2号背包里放东西的时候,第1号背包即再也不能放进任何物品,也就是说,背包是按顺序放进物品,先1后2。
(2)物品的处理也是按顺序的,从第1号物品开始到最后一个物品,每个物品只有两个情况,要么放进当前正在装物品的背包,要么放弃装入。装入的过程也是从1号背包开始一直到第n号背包。
在以上的前提下,有人提出了动态规划的方法来解题,如http://www.cnblogs.com/wen-ge/p/5442095.html.本文将利用树形结构来解决!
思路如下:
假设有如下测试用例
3 2 2
1 2 1
那么我们将会有以下的访问树:
数中的每一个节点都有自己专属的四个变量:(1).目前已经用了多少个袋子packets_used;(2)目前正在处理物品的编号index;(3)当前袋子的剩余容量;(4)目前已经装入袋中的物品的个数;这四个变量可以保证每一个物品应该如何装入哪一个袋子中。当袋子已经用尽时,停止处理。
那么对于1,2,1这三个物品中的每一个,按照数的深度遍历来处理对应的包裹是否加入到背包中,以上图的A,B两个状态为例。在状态A中,数的路径是001(表示第1,第2号物品不装入背包,到第3个物品才装入第1个背包),那么背包使用个数是1,物品装入的个数是1;同样的对于B状态的树的访问路径是111,则表示理论上(说是理论上,其实要考虑背包的个数,以及是否要重新启用一个新的背包)三个物品全部加入到背包中,但是由于在装入第1个物品之后,背包1剩下的体积无法再装入第二个物品,所以此时必须要启用一个新的背包,所以此时只能将第1号背包封住,启用第二号背包来装第2号物品,装入2号物品后背包2的剩余体积为0,不能装入第3号物品(这就是剪枝操作,经过剪枝操作之后的树的访问深度会大大减少,从而减少算法时间).
以下是代码部分:
#include<iostream>#include<vector>#include<list>#include<fstream>#include<string>#include<unordered_set>#include<map>#include<algorithm>#include<stack>using namespace std;class solution{public:void TheBiggestNumberOfGifts(int packets_used,int index,int leftv,int load){//index表示当前正在处理的物品下标if (index>gifts-1)return;if (data[index]<=leftv){//加入的情况不需要从新启用一个袋子if (load+1 > re)re = load+1;TheBiggestNumberOfGifts(packets_used,index+1,leftv-data[index],load+1);}else{//加入需要重新使用一个袋子if (packets_used + 1 <= number){//物品的最大体积必须不大于袋子的体积if(data[index]>volume)TheBiggestNumberOfGifts(packets_used+1, index + 1, volume, load);else {if (load+1 > re)re = load+1;TheBiggestNumberOfGifts(packets_used+1, index + 1, volume - data[index], load+1);}}}//不加入TheBiggestNumberOfGifts(packets_used,index+1,leftv,load);}vector<int>data;int gifts;//物品的总个数int volume;//每个袋子的体积int number;//袋子的总个数int re;//目前最大的物品装载数};int main(){//ifstream fin("C:\\Users\\caoyan\\Desktop\\data.txt");string str;int num,temp;vector<int>data;solution aa;cin >> num;while (num){cin >> aa.gifts >> aa.volume >> aa.number;aa.data.clear();for (int i = 0; i < aa.gifts;i++){cin >> temp;aa.data.push_back(temp);}aa.re = 0;aa.TheBiggestNumberOfGifts(1, 0, aa.volume, 0);cout <<aa.re<< endl;////分别代表已经用了多少个袋子,物品装载的起始下标,当前袋子的剩余容量,目前已装载物品的个数num--;}}然而得到的测试结果是:
在下就不懂了,为什么可以容量为11的背包可以装得下大于体积为11的物品,测试用例的设计人员你出来解释一下!!!!!
以下是我自己的测试数据是没问题的!!!!!数据如下:
测试结果:
- 完美世界2016实习生招聘编程题-小萌的包裹
- 完美世界2017校园招聘编程题
- 阿里巴巴2016实习生招聘编程题
- 完美世界2013校园招聘笔试题
- 网易2016机器翻译实习生招聘笔试编程题
- 完美世界 2016 笔试 编程第二题
- 完美世界2017实习生面试
- 2017百度实习生招聘编程题
- 2017腾讯实习生招聘笔试编程题
- 2017阿里实习生招聘考试编程题
- 2017阿里巴巴实习生招聘编程题
- 2017百度实习生招聘编程题
- 完美世界编程题2
- 完美世界笔试编程题
- 2016完美世界招聘笔试题———互联网Java开发
- 2013年完美世界校园招聘笔试题
- 2013年完美世界校园招聘笔试题
- 2013年完美世界校园招聘笔试题
- 内嵌的Jetty启动后访问503
- 萌新的Canvas笔记(三)
- Git学习 <day5>-分支
- [thinkphp5 学习笔记] model类型
- HDU 1203 I NEED A OFFER! (基础动态规划)
- 完美世界2016实习生招聘编程题-小萌的包裹
- Java 内部类、匿名内部类、抽象类
- Android 教你亲手打造酷炫的弹幕效果
- 直接插入排序
- Reverse Integer
- 二十、状态模式State(行为型)
- 2002: [Hnoi2010]Bounce 弹飞绵羊
- 一个小矩阵的翻转t=1为上下翻转, t=0为左右翻转
- HDU 5725/2016多校1C Game