拼多多笔试货运装箱那一题的贪心策略

贪心策略:
step1:将货物按重量从小到大排序,将重量大于200的直接装箱
step2:设置左右两个区间游标left和right,接着考虑到100+200这种临界情形,先将right左移到第一个小于200的下标处,将left右移到第一个大于100的下标处,将left~right区间内的货物首尾匹配,如果<=300就装箱,并mark这两个位置已经访问过,如果大于300就不装箱(right这个位置的货物也不装)将right左移一个位置继续匹配直到left == right
step3:在step2的基础上再将100和200重的货物加进来,并将left置0,right置为最后一个货重<=200的货物下标处,首尾匹配,先检验left和right这两个货物是否已mark过,如果mark了就left++或者right--,若都未被标记,当right处货重为100则直接将区间剩余货物一次性3箱这样带走,当right处货重>100时且和重<=300则将left和right处的货物一块装箱带走同时缩进left和right,>300则只能将right处货物装箱带走并缩进right
tips:比较关键的一个点就是100+200这种临界情况要考虑清楚,还有容易疏忽的就是区间内剩下货物全是100的时候就不能再首尾匹配了而应该3箱3箱这样子装箱带走
ps:有问题的欢迎指正
#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn = 1005;
int w[maxn];
bool mark[maxn];

int main(){
    int t,n = 0,res = 0;
    while(~scanf("%d",&t)){
        w[n] = t;
        mark[n++] = false;
    }
    sort(w,w+n);
    int left = 0,right = n - 1;
    while(right >= 0 && w[right] > 200){
        res++;
        right--;
    }
    //保存第一个<=200的元素下标
    int nr = right;
    while(right >= 0 && w[right] == 200){
        right--;
    }
    while(left < n && w[left] == 100){
        left++;
    }
    while(left < right){
        if(w[left] + w[right] <= 300){
            res++;
            mark[left] = mark[right] = true;
            left++;
            right--;
        }else{
            right--;
        }
    }
    right = nr;
    left = 0;
    while(left <= right){
        if(mark[left]){
            left++;
        }else if(mark[right]){
            right--;
        }else if(left == right){
            res++;
            break;
        }else if(w[right] == 100){
            int len = right - left + 1;
            res = res + len/3 + (len%3 > 0 ? 1 : 0);
            break;
        }else if(w[left] + w[right] <= 300){
            res++;
            left++;
            right--;
        }else{
            res++;
            right--;
        }
    }
    printf("%d\n",res);
    return 0;
}

#内推##拼多多##笔试题目#
全部评论
拼多多在26号19.00会做一个线上技术分享会,对技术部架构和岗位感兴趣的同学,想拿拼多多技术部offer的同学可以关注一下~~ 分享会链接在这里:  https://m.qlchat.com/topic/2000001645751647.htm?pro_cl=4
点赞 回复 分享
发布于 2018-07-25 22:27
感觉复杂了。策略可以很简单,排序后,最小(i)的和最大(j)的相加大于300的话,最大的直接装车j--;否则将最小的加到最大的上面去合成一个货物,i++; 最后考虑i,j相等的情况。
点赞 回复 分享
发布于 2018-07-23 17:36
我跟你类似  因为货物重量是[100,300],所以也是两个首位指针,如果weight[l]+weight[r] ==200&&l+1<r,会考虑三个100的情况,然后也是对成功装箱的货物标记为-1,然后最后再扫描一边非负的货物,但是通过率为55%。。不知道为啥
点赞 回复 分享
发布于 2018-07-23 15:43
补充一下题目:有一批货物重量为W1,W2,W3.....,其中100<=Wi<=300,用核载300的货车拉最少需要多少次
点赞 回复 分享
发布于 2018-07-23 15:04

相关推荐

04-02 16:49
门头沟学院 Java
_bloodstream_:我也面了科大讯飞,主管面的时候听说急招人优先考虑能尽快实习的,我说忙毕设,后面就一直没消息了
点赞 评论 收藏
分享
醉蟀:你是我今年见过的最美牛客女孩
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务