714 - Copying Books(二分)

该题是所谓“最大值尽量小”的典型代表,方法就是用二分猜这个最值,判断函数就是从前向后扫,尽量向后划,如果最后划出的组数比k小,那么显然可以划成k组。

代码如下:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int T,n,k,a[505];
bool P(int m) {
    int ans=0,cnt=1;
    for(int i=0;i<n;i++) {
        ans+=a[i];
        if(ans>m) {
            ans = a[i]; cnt++;
        }
    }
    if(cnt<=k) return true;
    else return false;
}
int main() {
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&k);
        ll l = 0,r = 0;
        for(int i=0;i<n;i++) {
            scanf("%d",&a[i]);
            r += a[i];
            if(l<a[i]) l = a[i];
        }
        ll m;
        while(r > l) {  //二分查找最大和的最小可能
            m = (l+r)/2;
            if(P(m)) r = m;
            else l = m+1;
        }
        int ans[505];
        memset(ans,0,sizeof(ans)); //用来记录每一部分的数字个数
        int cnt = 0;
        ll bbc = 0;
        for(int i=n-1;i>=0;i--){
            bbc += a[i];
            if(bbc>r){
                bbc = a[i]; cnt++;//但是这样做是有缺陷的,比如本来应该是 1 1 2的可能变成 0 2 2
                ans[cnt]++;
            }
            else ans[cnt]++;
        } cnt ++;
        int q = 0;
        for(int i=k-1;i>=0;i--){ //因此将为0的部分用后面的数补上
            if(ans[i]!=0) break;
            else {
                for(int j=i-1;j>=0;j--){
                    if(ans[j]>1){
                        ans[j]--; ans[i]++; break;
                    }
                }
            }
        }
        for(int i=k-1;i>=0;i--){    //打印
            for(int j=0;j<ans[i];j++){
                if(q==n-1) cout<<a[q++];
                else cout<<a[q++]<<' ';
            }
            if(q!=n)
            cout<<"/ ";
        }
        cout<<"\n";
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-20 01:20:25

714 - Copying Books(二分)的相关文章

UVa 714 - Copying Books 二分答案

题目链接:714 - Copying Books 解题思路 具体处理方法见代码 /************************************************************** Problem: User: youmi Language: C++ Result: Accepted Time: Memory: ****************************************************************/ //#pragma comm

uva 714 Copying Books (二分)

uva 714 Copying Books Before the invention of book-printing, it was very hard to make a copy of a book. All the contents had to be re-written by hand by so called scribers. The scriber had been given a book and after several months he finished its co

uva 714 - Copying Books(贪心 最大值最小化 二分)

题目描述开头一大堆屁话,我还仔细看了半天..其实就最后2句管用.意思就是给出n本书然后要分成k份,每份总页数的最大值要最小.问你分配方案,如果最小值相同情况下有多种分配方案,输出前面份数小的,就像字典序输出从小到大一样的意思. 这里用到贪心的方法,定义f(x)为真的条件是满足x为最大值使n本书分成k份,那么就是求x的最小值.如何确定这个x就是用的二分法,x一定大于0小于所有值的合,不断的二分再判断是否成立,成立就取左半边,不成立说明太小了就取右半边,写的时候还是没有把二分法理解透彻,我还怕会丢失

UVa 714 Copying Books(贪心 二分)

题意  把m数分成k组  使每组数的和的最大值最小  如果有多种分法 靠前的组的和尽量小 关键是找出那个最小的最大值   可以通过二分来找出  开始左端点为m个数中最大的数  右端点为m个数的和  若中点能将m个数分为小于等于k组  比它大的肯定都是可以的  中点变为右端点   否则中点变成左端点 然后就可以贪心逆向模拟了  从后往前每组选择尽量多的数直到剩下的数等于组数 #include <bits/stdc++.h> using namespace std; typedef long lo

【NOIP提高组2015D2T1】uva 714 copying books【二分答案】——yhx

Before the invention of book-printing, it was very hard to make a copy of a book. All the contents hadto be re-written by hand by so called scribers. The scriber had been given a book and after severalmonths he finished its copy. One of the most famo

714 - Copying Books——[贪心、二分查找]

Before the invention of book-printing, it was very hard to make a copy of a book. All the contents had to be re-written by hand by so called scribers. The scriber had been given a book and after several months he finished its copy. One of the most fa

UVA 714 Copying Books 抄书 (二分)

题意:把一个包含m个正整数的序列划分成k个非空的连续子序列.使得所有连续子序列的序列和Si的最大值尽量小. 二分,每次判断一下当前的值是否满足条件,然后修改区间.注意初始区间的范围,L应该为所有正整数中的最大值,否则应该判断时注意.输出解的时候要使字典序最小,所以从后面贪心. #include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxm = 501; ll p[maxm]; bool vis[

UVa 714 Copying books 贪心+二分 最大值最小化

题目大意: 要抄N本书,编号为1,2,3...N, 每本书有1<=x<=10000000页, 把这些书分配给K个抄写员,要求分配给某个抄写员的那些书的编号必须是连续的.每个抄写员的速度是相同的,求所有书抄完所用的最少时间的分配方案. 题目中的要求是去求划分的子序列的最大值尽量小,最大值最小化,如果从划分的角度看,无法获得好的思路,我们可以从值得角度考虑,所要求的最小的最大值必定是从[amax,sum(总和)]中取得的,那么我们可以二分法的方式猜测一个数字,看它是否满足要求,如果满足要求,我们可

UVA 714 Copying Books

题意: 要抄N本书,编号为1,2,3...N, 每本书有1<=x<=10000000页, 把这些书分配给K个抄写员,要求分配给某个抄写员的那些书的编号必须是连续的.每个抄写员的速度是相同的,求所有书抄完所用的最少时间的分配方案. 分析: 这个题以前做过.就是先二分出来,最大的区间最小值.然后一重循环查找输出/就好 代码: #include <iostream>#include <cstring>#include <cstdio>#include <al