把可能的进行二分判断,判断的时候尽量向右取,一直取到不能去为止,这样才有可能成功分割。

判断是否可以把up作为最大值的代码:

bool judge(LL up){
    if(up < Big) return false; //Big是数组中最大值,如果up小于最大值是不可能成功划分的
    LL sum = 0;
    int cnt = 0;
    for(int i = 0; i < n; ){
        sum = 0;
        while(i < n){
            sum += a[i];
            if(sum <= up) ++i;
            else break;
        }
        ++cnt;
    }
    if(cnt <= k) return true; //成功划分
    return false;
}

值得注意的是,最后得到最小的最大值时应该如何划分,题目要求前面的尽量小,那么就从后面尽可能多的划分,但是不能只满足小于等于up,也要考虑到组成k个序列,不能让某些序列为空。

AC代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = 500 + 5;
int a[maxn], vis[maxn];
int Big = -1; //Biggest number
int n,k; //Divid n numbers to k squences

bool judge(LL up){
    if(up < Big) return false;
    LL sum = 0;
    int cnt = 0;
    for(int i = 0; i < n; ){
        sum = 0;
        while(i < n){
            sum += a[i];
            if(sum <= up) ++i;
            else break;
        }
        ++cnt;
    }
    if(cnt <= k) return true;
    return false;
}

LL Binary_Search(LL x, LL y){ //[x,y]
    while(x < y){
        LL mid = x + (y - x) / 2;
        bool ok = judge(mid);
        if(ok) y = mid;
        else x = mid + 1;
    }
    return y;
}

int main(){
    int T;
    scanf("%d", &T);
    while(T--) {
        memset(vis, 0, sizeof(vis));
        LL sum = 0;
        Big = -1;
        scanf("%d%d",&n,&k);
        for(int i = 0; i < n; ++i){
            scanf("%d",&a[i]);
            sum += a[i];
            Big = max(Big, a[i]);
        }
        LL up = Binary_Search(1, sum);
        LL div;
        int cnt = 0;
        for( int  i = n-1; i >= 0;){
            div = 0;
            while(div <= up && i >= 0 && i + 1 >= k - cnt){
                div += a[i];
                if(div <= up) --i;
            }
            ++cnt;
            if(i >= 0) vis[i] = 1;
        }
        //print the answer
        for(int i = 0; i < n; ++i){
            if(i == n-1) printf("%d\n", a[i]);
            else printf("%d ", a[i]);
            if(vis[i]) printf("/ ");
        }
    }
    return 0;
}

如有不当之处欢迎指出!

UVA-714 二分的更多相关文章

  1. UVa 714 (二分) Copying Books

    首先通过二分来确定这种最大值最小的问题. 假设每个区间的和的最大值为x,那么只要判断的时候只要贪心即可. 也就是如果和不超过x就一直往区间里放数,否则就开辟一个新的区间,这样来判断是否k个区间容得下这 ...

  2. UVa 714 Copying Books(二分)

    题目链接: 传送门 Copying Books Time Limit: 3000MS     Memory Limit: 32768 KB Description Before the inventi ...

  3. UVa 714 Copying Books - 二分答案

    求使最大值最小,可以想到二分答案. 然后再根据题目意思乱搞一下,按要求输出斜杠(这道题觉得就这一个地方难). Code /** * UVa * Problem#12627 * Accepted * T ...

  4. UVA 714 Copying Books 二分

    题目链接: 题目 Copying Books Time limit: 3.000 seconds 问题描述 Before the invention of book-printing, it was ...

  5. UVA 714 Copying Books 最大值最小化问题 (贪心 + 二分)

      Copying Books  Before the invention of book-printing, it was very hard to make a copy of a book. A ...

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

    题目描写叙述开头一大堆屁话,我还细致看了半天..事实上就最后2句管用.意思就是给出n本书然后要分成k份,每份总页数的最大值要最小.问你分配方案,假设最小值同样情况下有多种分配方案,输出前面份数小的,就 ...

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

    题目大意: 要抄N本书,编号为1,2,3...N, 每本书有1<=x<=10000000页, 把这些书分配给K个抄写员,要求分配给某个抄写员的那些书的编号必须是连续的.每个抄写员的速度是相 ...

  8. UVA 714 Copying Books 抄书 (二分)

    题意:把一个包含m个正整数的序列划分成k个非空的连续子序列.使得所有连续子序列的序列和Si的最大值尽量小. 二分,每次判断一下当前的值是否满足条件,然后修改区间.注意初始区间的范围,L应该为所有正整数 ...

  9. 紫书 例题8-10 UVa 714 (二分答案)

    这道题让最大值最小, 显然是二分答案 当题目求的是最大值最小, 最小值最大, 这个时候就要想到二分答案 为什么可以二分答案呢, 因为这个时候解是单调性的, 如果简单粗暴一点 就全部枚举一遍, 验证答案 ...

  10. UVA - 714 Copying Books (抄书)(二分+贪心)

    题意:把一个包含m个正整数的序列划分成k个(1<=k<=m<=500)非空的连续子序列,使得每个正整数恰好属于一个序列(所有的序列不重叠,且每个正整数都要有所属序列).设第i个序列的 ...

随机推荐

  1. ListCtrl控件

    一 CListCtrl类型 LVS_EDITLABELS LVS_OWNERDRAWFIXED LVS_REPORT LVS_SHOWSELALWAYS LVS_SINGLESEL LVS_SMALL ...

  2. Can’t open /dev/* exclusively. Mounted filesystem?解决

    1 错误提示:Can’t open /dev/* exclusively. Mounted filesystem? 做完软件RAID之后,根据鸟哥书上的操作,其实没有真正删除软件RAID,导致出现如下 ...

  3. JFreeChart绘制折线图实例

    JFreeChart是JAVA平台上的一个开放的第三方图表绘制类库.只要下载JFreeChart的类库,导入项目即可使用.下面是一个绘制折线图的实例.各处注释都已经写的比较清晰了. package c ...

  4. 【转】Shell执行MySql操作

    mysql  -hhostname -Pport -uusername -ppassword  -e  相关mysql的sql语句,不用在mysql的提示符下运行mysql,即可以在shell中操作m ...

  5. unicode文件处理(如果是ANSI编码就不需要了)

    1.unicode文件的打开必须用rb模式. 3.wchar_t str[100] = { 0 }; 这个占200个字节. 2.宽字符对应的处理 fgetc fgetwc fputc fputwc f ...

  6. Web安全之CSP

    内容安全策略(Content-Security-Policy,简称CSP) 概念: 内容安全策略(CSP)是一种web应用技术用于帮助缓解大部分类型的内容注入攻击,包括XSS攻击和数据注入等,这些攻击 ...

  7. iOS-状态栏字体颜色【白色】【Xcode9.1】

    Xcode9之前 设置状态栏颜色首先在info.plist文件中,加入UIViewControllerBasedStatusBarAppearance = false: <key>UIVi ...

  8. 关于metaclass,我原以为我是懂的

    关于Python2.x中metaclass这一黑科技,我原以为我是懂的,只有当被打脸的时候,我才认识到自己too young too simple sometimes native. 为什么之前我认为 ...

  9. 洛谷 [P1129] [ZJOI2007] 矩阵游戏

    这竟然是一道二分图 乍一看,可能是用搜索做,但是这个数据范围,一定会T. 我们观察发现,无论怎样变换,同一行的一定在同一行,同一列的一定还在同一列.所以说,一行只能配一列.这样,我们的目标就是寻找是否 ...

  10. Git点滴记录

    合并多个commit记录 假设我们当前有三个commit信息,现在要将commit hash为 23f92c 和 409978 合并 //git rebase -i HEAD~3 那么我们可以使用 r ...