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
  • 相关阅读:
    二叉搜索查找排序树
    多项式运算
    赫夫曼编码及应用
    利用python画出动态高优先权优先调度
    利用python画出SJF调度图
    支持向量机
    fisher线性分类器
    Codeforces Round #520 (Div. 2)
    Codeforces Round #510 (Div. 2)
    Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final)
  • 原文地址:https://www.cnblogs.com/wizarderror/p/11314127.html
Copyright © 2011-2022 走看看