2019牛客暑期多校训练营(第六场)D.Move

2019牛客暑期多校训练营(第六场)D.Move

题目链接

题目描述

After the struggle of graduating from college, TangTang is about to move from a student apartment to his new home.

TangTang has n items to move, the i-th of which is of volume v i v_i vi. He can pack all these items into at most K boxes of the same volume.

TangTang is so clever that he uses the following strategies for packing items:

  • Each time, he would put items into a box by the next strategy, and then he would try to fill another box.
  • For each box, he would put an unpacked item of the largest suitable volume into the box repeatedly until there is no such item that can be fitted in the box.

Now, the question is what is the minimum volume of these boxes required to pack all items.

输入描述:

There are multiple test cases. The first line contains an integer T ( 1 ≤ T ≤ 20 ) T (1 \leq T \leq 20) T(1T20), indicating the number of test cases. Test cases are given in the following.

For each test case, the first line contains two integers n , K ( 1 ≤ n , K ≤ 1000 ) n, K (1 \leq n, K \leq 1000) n,K(1n,K1000), representing the number of items and the number of boxes respectively.

The second line contains n integers v 1 , v 2 , … … , v n ( 1 ≤ v 1 , v 2 , … , v n ≤ 1000 ) v_1, v_2, \ldots…, v_n (1 \leq v_1, v_2, \ldots, v_n \leq 1000) v1,v2,,vn(1v1,v2,,vn1000), where the i-th integer v i v_i vi represents the volume of the i-th item.

输出描述:

For each test case, output “Case #x: y” in one line (without quotes), where x indicates the case number starting from 1, and y denotes the answer to this test case.

示例1

输入

1
5 3
1 2 3 4 5

输出

Case #1: 5

一开始我想的是二分,但是一直有问题,后来发现这题的答案不满足二分的规律,然后就直接暴力了,因为答案就在 [ s u m n , s u m n + m a x v ] [\frac{sum}{n},\frac{sum}{n}+maxv] [nsum,nsum+maxv] 上,最多1000次判断,每次 c h e c k check check 的复杂度为 O ( n ∗ l o g n ) O(n*logn) O(nlogn),所以直接枚举答案就能过,
AC代码如下:

#include
using namespace std;
typedef long long ll;
const int N=1e3+5;
int t,n,k,a[N],vis[N],sum;
bool check(int x){
    int res,cnt=0;
    fill(vis,vis+N,0);
    for(int i=0;i<k;i++){
        res=x;
        for(int j=0;j<n;j++){
            if(!vis[j]&&res>=a[j]){
                res-=a[j];
                cnt++;
                vis[j]=1;
            }
        }
        if(cnt==n) return 1;
    }
    return 0;
}
int main(){
    scanf("%d",&t);
    for(int u=1;u<=t;u++){
        sum=0;
        scanf("%d%d",&n,&k);
        for(int i=0;i<n;i++) scanf("%d",&a[i]),sum+=a[i];
        sort(a,a+n,greater<int>{});
        for(int i=sum/k;i<=sum/k+a[0];i++){
            if(check(i)){
                printf("Case #%d: %d\n",u,i);
                break;
            }
        }
    }
    return 0;
}

你可能感兴趣的:(暴力,思维,牛客)