zoukankan      html  css  js  c++  java
  • UVa 714 抄书 二分答案

    题意:
    把一个包含m个正整数的序列划分成k个(1≤k≤m≤500)非空的连续子序列,使得每个正 整数恰好属于一个序列。设第i个序列的各数之和为S(i),你的任务是让所有S(i)的最大值尽 量小。例如,序列1 2 3 2 5 4划分成3个序列的最优方案为1 2 3 | 2 5 | 4,其中S(1)、S(2)、S(3) 分别为6、7、4,最大值为7;如果划分成1 2 | 3 2 | 5 4,则最大值为9,不如刚才的好。每个 整数不超过107。如果有多解,S(1)应尽量小。如果仍然有多解,S(2)应尽量小,依此类推。
    分析:
    二分最大值,用O(n)扫一遍判断,T=O(nlogn)。
    打印最优解的时候比较麻烦,我WA了几次,扫后面尽可能取多的数,然后因为要有k个划分,也就是要k-1个’’,所以处理到还剩下k个数的时候每隔一个放一个’’。(注意下标从0开始)

    #include<cstdio>
    #include<stack>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N=555;
    int a[N];
    int n,k;
    bool ok(ll x)
    {
        int tot=k-1;
        ll t=0;
        for(int i=0;i<n;i++){
            t+=a[i];
            if(t>x){
                i--; tot--; t=0;
                if(tot<0)return 0;
            }
        }
        return 1;
    }
    int main()
    {
    
        int T; scanf("%d",&T);
        while(T--){
            scanf("%d%d",&n,&k);
            for(int i=0;i<n;i++)scanf("%d",&a[i]);
            if(k==1){
                for(int i=0;i<n-1;i++)printf("%d ",a[i]);
                printf("%d
    ",a[n-1]);continue;
            }
            ll l=0,r=5000000000;
            while(l<r){
                ll m=l+(r-l)/2;
                if(ok(m))r=m;
                else l=m+1;
            }
    
            stack<int>s;
            ll t=0;
            for(int i=n-1;i>=0;i--){
                t+=a[i];
                if(i+1==k-1)s.push(i),k--; //还剩下i+1个数,最多可以划分成k个,那么就是放k-1个'/'
                else if(t>l){
                    s.push(i);
                    i++; k--;
                    t=0;
                }
            }
            int i;
            for(i=0;i<n-1;i++){
                printf("%d ",a[i]);
                if(i==s.top()){
                    s.pop();
                    printf("/ ");
                }
                if(s.empty())break;
            }
            for(i=i+1;i<n-1;i++)printf("%d ",a[i]);
            printf("%d
    ",a[n-1]);
        }
        return 0;
    }
  • 相关阅读:
    sql常用语句
    java学习(东软睿道)2019-09-06(预课)《随堂笔记》
    Servlet和JSP学习总结
    由字符集的转换想到的问题
    mysql主从搭建
    CentOS 源码安装MySQL5.7
    Linux搭建FTP服务器
    连接MySQL报错误代码 ERROR 1045时的解决方案
    [js]使用百度编辑器uediter时遇到的一些问题(span,div等被过滤)
    [css]将textarea前的文字设置在左上角
  • 原文地址:https://www.cnblogs.com/01world/p/5651205.html
Copyright © 2011-2022 走看看