zoukankan      html  css  js  c++  java
  • 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
    ",kase++,ans);
        }
        return 0;
    }
    
  • 相关阅读:
    倍增
    「BZOJ 2152」聪聪可可
    「POJ 1741」Tree
    点分治
    高斯消元
    网络流24题之餐巾计划问题
    网络流24题之骑士共存问题
    网络流24题之方格取数问题
    网络流24题之负载平衡问题
    网络流24题之分配问题
  • 原文地址:https://www.cnblogs.com/ttttttttrx/p/11407581.html
Copyright © 2011-2022 走看看