zoukankan      html  css  js  c++  java
  • 2019牛客暑期多校训练营(第六场)D-Move

    >传送门<

    题意:

    你有n件行李,有k个箱子体积相同的箱子,遵循下面的规则将行李放进箱子里面

    每次都取当前最大的可以放进箱子的行李放进箱子,如果该箱子放不进任何行李那么就换一个新的箱子再按照这一条规则进行放行李

    请问箱子最小的体积是多少可以放进所有行李

    思路:

    还是菜鸡的我比赛的时候没有思路,也木有想法,赛后再看题解给出的竟然是暴力枚举!!!

    下面官方题解就分析的挺好的

    • 考虑到答案下界显然为 ceil(sum / k)
    • 上界为 ceil(sum / k) + maxV

    • 假设某个答案 ans 装不下,那么每个箱子的剩余空间都 < maxV
    • 此时 k * (ans - maxV + 1) <= sum
    •  ans <= sum/k + maxV - 1

    • check 一个答案的复杂度为 O(nlogn)
    • 所以我们直接在这个范围内枚举答案,复杂度为 O(maxV * nlogn)

    Code

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1000 + 7;
    int v[maxn], n, k, used[maxn];
    bool check(int x)
    {
        for(int i = 1; i <= n; i++) used[i] = 0;
        for(int i = 1; i <= k; i++){
            int tmp = 0;
            for(int j = n; j >= 1; j--){
                if(!used[j] && tmp + v[j] <= x){
                    used[j] = 1;
                    tmp += v[j];
                }
            }
        }
        for(int i = 1; i <= n; i++) if(!used[i]) return false;
        return true;
    }
    int main()
    {
        int T;
        scanf("%d", &T);
        for(int cas = 1; cas <= T; cas++){
            scanf("%d%d", &n, &k);
            int sum = 0;
            for(int i = 1; i <= n; i++) scanf("%d", v + i), sum += v[i];
            sort(v + 1, v + n + 1);
            int ans = 1;
            for(int i = sum / k; i <= sum; i++){
                if(check(i)){
                    ans = i;
                    break;
                }
            }
            printf("Case #%d: %d
    ", cas, ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    解惑开源项目协作流程
    结合webpack 一步一步实现懒加载的国际化简易版方案
    SEO优化之——hreflang(多语言网站优化)
    pandas数据分析常用
    多任务: 多进程与多线程
    linux基础知识
    python常用模块之sys, os, random
    递归函数(初级难点)
    内置函数
    函数
  • 原文地址:https://www.cnblogs.com/wizarderror/p/11314127.html
Copyright © 2011-2022 走看看