这套题难啊。。好多坑点。而且想了好久。交卷两小时。。想了一晚上。

第一题还是不知道怎么dp的。。可能要坑一下明天补。。

如果有大佬能指点下我就更好了QAQ。我是真的菜。。

我来补题了哈哈哈哈哈哈哈哈哈!!终于过了

 


 

 

试题链接:2020校招算法工程师方向笔试题

 

5、 外卖小哥的保温箱

题意:众所周知,美团外卖的口号是:”美团外卖,送啥都快”。身着黄色工作服的骑手作为外卖业务中商家和客户的重要纽带,在工作中,以快速送餐突出业务能力;工作之余,他们会通过玩智力游戏消遣闲暇时光,以反应速度彰显智慧,每位骑手拿出装有货物的保温箱,参赛选手需在最短的时间内用最少的保温箱将货物装好。

 

我们把问题简单描述一下:

 

1 每个货物占用空间都一模一样

 

2 外卖小哥保温箱的最大容量是不一样的,每个保温箱由两个值描述: 保温箱的最大容量 bi ,当前已有货物个数 ai ,(ai<=bi)

 

3 货物转移的时候,不必一次性全部转移,每转移一件货物需要花费 1秒 的时间

【美团点评】2020校招算法工程师方向笔试题

 

 

题解:我这个题用贪心只过了30%。。而且我花了一晚上时间想怎么dp。。想不出来。

讨论区大佬说贪心只能得到最优k。QAQ我先坑一下。。明天补吧可能

终于AC了。感谢gg倾情指导。虽然还是找了半下午的bug//

 

这个题是一个背包dp。嗯,我背包dp学的可差了。

我们用dp[i]来表示当前容量为i时所需要的最少背包数。(货物为goods[],容量为cap[])

外层需要遍历所有的背包容量,内层来做这个dp处理。(外层这里用i,内层用j来表示)

此时的状态转移方程也就是dp[j] = min(dp[j],dp[j-cap[i]]+1),

这里就需要注意到j-cap[i]因为j是从sum_cap遍历到1的。防止负数情况出现,做一个负数为0的处理。

然后我们这里只是做了使用最少背包数的dp处理。但是并不知道time。time是由货物的转移来决定的。所以我们用一个额外的数组weight[]来表示货物多的。因为转移货物越多,花时间越长,所以保存货物多的情况。

那我们此时会出现三种情况。

1、dp[j] < dp[j-cap[i]]+1  当前背包大于,那么直接不处理。因为我们要保证背包最小

2、dp[j] > dp[j-cap[i]]+1  比当前背包要小,那么更新背包,并且将货物加上。

3、dp[j] = dp[j-cap[i]]+1  相同的情况,保证留下的货物是最大的。

背包这个过程进行完以后,进行一个遍历,找最优的k,以及最优k对应留下的背包里的货物总量。

那么我们所需要的时间t = sum_goods-max_weight啦!!!

分析就是上面这些,代码可能会更清晰。

 

代码:

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1e5+10;
 4 int n;
 5 
 6 int goods[maxn];
 7 int cap[maxn];
 8 int dp[maxn]; 
 9 int weight[maxn];
10 
11 int main(){
12     cin>>n;
13     int sum_goods = 0;
14     int sum_cap = 0;
15     for(int i = 0;i < n; i++){
16         cin>>goods[i];
17         sum_goods += goods[i];
18     }
19     for(int i = 0;i < n ; i++){
20         cin>>cap[i];
21         sum_cap += cap[i];
22     }
23 
24     memset(dp,0x3f,sizeof(dp));
25     memset(weight,0,sizeof(weight));
26 
27     dp[0] = 0;
28     weight[0] = 0;
29     for(int i = 0; i < n ;i++){
30         //遍历容量dp[j]:容量为j时需要的最少背包数
31         for(int j = sum_cap; j > 0 ; j--){
32             int res = max(j-cap[i],0);
33             //大于直接下一个
34             if(dp[j] < dp[res]+1)   continue;
35             //小于,更新一下背包数。并且把货物容量更新
36             else if(dp[j] > dp[res]+1){
37                 dp[j] = dp[res]+1;
38                 weight[j] = weight[res]+goods[i];
39             }
40             //相等的时候取货物大的情况
41             else{
42                 weight[j] = max(weight[j],weight[res]+goods[i]);
43             }
44         }
45     }
46 
47     int k = 0x3f;
48     int max_weight = 0;
49 
50     for(int i = sum_goods; i <= sum_cap; i++){
51         if(dp[i] < k){
52             k = dp[i];
53             max_weight = weight[i];
54         }
55         else if(dp[i] == k){
56             max_weight = max(max_weight,weight[i]);
57         }
58     }
59 
60     cout<<k<<" "<<sum_goods-max_weight<<endl;
61 
62 
63     return 0;
64 }
View Code

相关文章:

  • 2022-02-11
  • 2021-11-30
  • 2022-12-23
  • 2021-10-03
  • 2021-08-07
  • 2022-01-11
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-11-23
  • 2022-12-23
  • 2022-12-23
  • 2021-04-09
  • 2022-12-23
相关资源
相似解决方案