2019牛客竞赛第六场D Move 宏观单调,部分不单调

Move

题意

有k个体积相同的箱子,有个憨憨有固定的装箱策略,每次都只装可以装的重量中最大的东西,求箱子的最小提及

分析

看起来可以二分,但由于他的装箱策略有点蠢,所以只在宏观上满足单调性,在特别小的区间没有单调性,比赛的时候也想到了没有单调性,但是没想清楚在宏观上满足单调性,所以写了二分没过,就心态崩了,赛后发现只要在二分出来的值左右找一个满足的最小的就能过。。。。还是太年轻了

hack:15 5 • 39 39 39 39 39 60 60 60 60 60 100 100 100 100 100,199 为一个合法的答案,但 200 不是,201 也不是。

#include<bits/stdc++.h>
#define pb push_back
#define F first
#define S second
#define pii pair<int,int>
#define mkp make_pair
using namespace std;
const int maxn=2005;
const int inf=1e7;
int a[maxn];
int n,k;
multiset<int>s;
   
int check(int mid){
    s.clear();
    for(int i=1;i<=n;i++)s.insert(a[i]);
    for(int i=0;i<k;i++){
        /*
            auto it=(--s.end());
            int vl=mid;
            if((*it)>mid){
                return 0;
            }
            vl-=(*it);
            s.erase(it);
        */
   
        int vl=mid;
        if(s.empty())return 1;
        while(vl>0){
            //cout<<vl<<endl;
            auto z=s.upper_bound(vl);
            if(z==s.begin()){
                /*if(*z<=vl){
                    vl-=*z;
                    s.erase(z);
                    cnt++;
                  //  cout<<cnt<<endl;
                    if(s.empty())return 1;
                    break;
                }
                if{
                    break;
                }*/
                break;
            }
            --z;
            //if(*z>vl)break;
            vl-=(*z);
            s.erase(z);
            if(s.empty())return 1;
        }
    }
    if(s.empty())return 1;
    else return 0;
}
int main(){
    int t;
    scanf("%d",&t);
    int kase=1;
    while(t--){
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        sort(a+1,a+1+n);
        int l=1,r=inf,ans=inf;
        while(l<=r){
            int mid=(l+r)>>1;
            if(check(mid)){
                ans=min(ans,mid);
                r=mid-1;
            }
            else l=mid+1;
        }
        for(int i=max(1,ans-100);i<=ans+100;i++){
            if(check(i)){
                ans=i;
                break;
            }
        }
        printf("Case #%d: %d\n",kase++,ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ttttttttrx/p/11407581.html
今日推荐