• 「个人训练」Copying Books(UVa714)


    好久不更新主要是怠惰了。。。。还要加强训练。

    题意分析与思路

    注意到这样一句话:

    our goal is to minimize the maximum number of pages assigned to a single scriber. Your task is to find the optimal assignment.

    这种最大化最小、最小化最大,显然是二分。

    如何二分呢,枚举分成k份中各份的最大值,判断在$max_t$的情况下能否分成$le k$份,能的话那么我们的$max_t$还能更小,不然就得变大。虽然思路很简单,但是由于不熟练,还是写的满磕磕绊绊的,对状态细节的把握不熟练。

    代码

    #include <bits/stdc++.h>
    #define MP make_pair
    #define PB push_back
    #define fi first
    #define se second
    #define ALL(x) (x).begin(),(x).end()
    #define ZERO(x) memset((x),0,sizeof(x))
    typedef long long ll;
    typedef unsigned long long ull;
    using namespace std;
    
    int p[505],m,k;
    bool judge(int threshold)
    {
        int tmp=p[m],cnt=1;
        for(int i=m-1;i>=1;--i)
        {
            if(tmp+p[i]<=threshold)
            {
                tmp+=p[i];
            }
            else 
            {
                cnt++;
                tmp=p[i];
            }
        }
        if(cnt<=k) return true;
        else return false;
    }
    
    int main()
    {   
        int kase; cin>>kase;
        while(kase--)
        {
            cin>>m>>k;
            ll l=-1,r=0;
            for(int i=1;i<=m;++i)
            {
                cin>>p[i];
                r+=p[i];
                l=max(l,(ll)p[i]);
            }
            while(l<r)
            {
                int mid=(l+r)/2;
                if(judge(mid)) r=mid;
                else l=mid+1;
            }
            int tmp=0,cnt=1;
            bool cur[505]; memset(cur,false,sizeof(cur));
            //cout<<l<<" "<<r<<endl;
            for(int i=m;i>=1;--i)
            {
                if(i<=k-cnt) { cur[i]=true; cnt++; /*cout<<i<<" set"<<endl;*/ } 
                else
                {
                    if(tmp+p[i]<=l)
                    tmp+=p[i];
                    else
                    {
                        //cout<<i<<" put"<<endl;
                        tmp=p[i];
                        cur[i]=true;
                        cnt++;
                    }
                }
    
            }
            for(int i=1;i<=m;++i)
            {
                cout<<p[i];
                if(i==m) cout<<endl;
                else if(cur[i]) cout<<" / ";
                else cout<<" ";   
            }
        }
        return 0;
    }
    如非注明,原创内容遵循GFDLv1.3发布;其中的代码遵循GPLv3发布。
  • 相关阅读:
    蓝桥杯 网络寻路
    ny33 蛇形填数
    集合运算 蓝桥杯 set容器
    蓝桥杯 回形取数
    bam/sam格式说明--转载
    samtools一些文档
    Linux批量更改文件后缀-转载
    GATK--使用转载
    Linux下wget下载整个FTP目录(含子目录)--转载
    CRLF line terminators导致shell脚本报错:command not found --转载
  • 原文地址:https://www.cnblogs.com/samhx/p/UVa-714.html
Copyright © 2020-2023  润新知