牛客多校第六场 D move 枚举/机智题

题意:

有个家伙装东西,他的策略是贪心,每次装进去这个盒子能装下的最大的东西,直到把这个盒子装满,再去装下一个盒子。

给出盒子的数量k和一些东西的重量,问你最小需要多大的盒子才能以这种贪心策略装下。

题解:

如果某个解可行,比它大的值未必可行,比如有15个物品,5个39,5个60,5个100,5个盒子,那么盒子大小199可以,200不行,201也不行。所以不能二分。

首先,显然答案下界为ceil(sum/k)。

设最大的物品重量为maxv,假如某个ans装不下,那么在此ans下,装下除maxv外所有物品后,所有箱子的剩余空间都小于maxv

因此,ans*k<sum-maxv+k*maxv

只需在[ceil(sum/k),ceil(sum/k+(k-1)*maxv)]区间内枚举即可。

判断一个ans的可行性复杂度是nlogn

#include<bits/stdc++.h>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAXN 1005
#define mem(a,b) memset(a,b,sizeof a)
#define rep(i,n,m) for(int i=n;i<=m;++i)
const int MOD = 9973;
inline int read()
{
    int x = 0, f = 1;
    char c = getchar();
    while (c<'0' || c>'9')
    {
        if (c == '-') f = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9')
    {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x * f;
}
int v[MAXN], n, k, num[MAXN], vis[MAXN],num1[MAXN];
bool check(int vlo)
{
    int nu = k;
    mem(vis, 0);
    //是否可以装完所有物品,贪心的装,尽量装大的,然后再补漏
    int left = n;
    //rep(i, 1, 1000) num1[i] = num[i];
    int maxx = n,no=1;
    while (nu)
    {
        int sp = vlo;
        for (int i = maxx; i > 0; --i)
        {
            if (sp < v[no]) break;
            if (sp >= v[i] && !vis[i])
            {
                sp -= v[i]; vis[i] = 1; left--;
                if (!sp) break;
            }
        }
        while (vis[maxx]) maxx--;
        while (vis[no]) no++;
        nu--;
    }
    if (!left) return 1;
    return 0;
}
int main()
{
    int T = read();
    for(int tt=1;tt<=T;++tt)
    {
        int sum = 0;
        n = read(), k = read();
        mem(num, 0);
        mem(num1, 0);
        rep(i, 1, n) v[i] = read(), sum += v[i];
        sort(v + 1, v + 1 + n);
        int bi = sum / k;
        if (sum % k) bi++;
        int beg = max(v[n], bi);
        int ans=beg;
        for (int i = beg; i <= 1000000; ++i)
        {
            if (check(i)) {
                ans = i; break;
            }
        }
        printf("Case #%d: %d\n", tt,ans);
    }
}

猜你喜欢

转载自www.cnblogs.com/isakovsky/p/11296773.html
今日推荐