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[maxm];

int k,m;

inline bool P(ll x)
{
    int cnt = 1;
    ll cur = p[0];
    for(int i = 1; i < m; i++){
        if(cur + p[i]<=x) cur += p[i];//if a[i] > x false
        else cur = p[i],cnt++;
    }
    return cnt<=k;
}

int main()
{
    //freopen("in.txt","r",stdin);
    int N; scanf("%d",&N);
    while(N--){
        scanf("%d%d",&m,&k);
        ll sum = 0,Max = -1;;
        for(int i = 0; i < m; i++) scanf("%lld",p+i),sum+=p[i],Max = max(Max,p[i]);
        ll L,R,mid;
        for(L = Max,R = sum; L < R; P(mid)?R=mid:L=mid+1) mid = (L+R)>>1;

        memset(vis,0,sizeof(vis));
        ll cur = p[m-1]; int kk = k-1;
        for(int i = m-2; i>=0&&kk; i--) {
            if(cur+p[i]>L||i<kk) vis[i]=true,cur = p[i],kk--;
            else cur += p[i];
        }
        printf("%lld",p[0]); if(vis[0]) printf(" /");
        for(int i = 1; i < m; i++){
           printf(" %lld",p[i]); if(vis[i]) printf(" /");
        }
        putchar(‘\n‘);
    }
    return 0;
}
时间: 2024-11-09 01:24:07

UVA 714 Copying Books 抄书 (二分)的相关文章

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(贪心 二分)

题意  把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

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

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

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

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

UVa 714 - Copying Books 二分答案

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

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(

UVA 714 Copying Books

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

POJ 1505 (Copying Books)(经典二分)

Description 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