• 4thweek.P_problemB .poj1505copy books.二分法


    题目大意:

    有m本书,k个抄写员。m本书的页码分别为 p1,p2……pm……。他们同时开始抄写且工作效率相同。要求分配给抄写员们若干书,每个抄写员要抄写的书的顺序必须是连续相邻的。

    请你分配书使他们在最少的时间里完成抄写任务。

    分析:

    使每个抄写员分配到的页数的最大值尽可能小。最大值的最小化问题加二分法应用。

    输入输出案例:

    Sample Input 

    2
    9 3
    100 200 300 400 500 600 700 800 900
    5 4
    100 100 100 100 100
    

     

    Sample Output

    100 200 300 400 500 / 600 700 / 800 900
    100 / 100 / 100 / 100 100
    

    代码如下:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 
     6 int n,k;
     7 int a[505];
     8 long long tot;
     9 int maxa;
    10 
    11 void Init()
    12 {
    13 cin>>n>>k;
    14 tot=0;
    15 maxa=-1;
    16 for(int i=0;i<n;i++)
    17 {
    18     cin>>a[i];
    19     tot+=a[i];
    20     maxa=max(a[i],maxa);  //明确最大页码的范围是:[maxa,tot].
    21 }
    22 }
    23 
    24 int deal(long long num)
    25 {
    26     long long c=0;
    27     int sum=1;
    28     for(int i=0;i<n;i++)
    29         if(c+a[i]<=num)
    30            c+=a[i];
    31         else
    32         {
    33             c=a[i];
    34             sum++;
    35         }
    36     return sum;
    37 }
    38 
    39 void print(long long num)
    40 {
    41     int last[510];
    42    long long done = 0;
    43   memset(last, 0, sizeof(last));
    44   int remain = k;
    45   for(int i = n-1; i >= 0; i--)
    46     {
    47     if(done + a[i] > num || i+1 < remain)
    48      {
    49       last[i] = 1;
    50       remain--;
    51       done = a[i];
    52      }
    53     else
    54       done += a[i];
    55 
    56     }
    57   for(int i = 0; i < n-1; i++)
    58     {
    59       printf("%d ", a[i]);
    60       if (last[i])
    61       printf("/ ");
    62     }
    63     printf("%d
    ", a[n-1]);
    64 }
    65 
    66 void Do()
    67 {
    68   long long l,r,m;
    69   l=maxa;
    70   r=tot;
    71   while(l<r)
    72   {
    73       m=l+(r-l)/2;   //二分,将抄写页码最大值区间缩小一半
    74      if(deal(m)<=k) r=m;    //如果当前分配方法能分配额份数小于抄写员人数,则应把区间上限减小(区间缩小一半),
    75      else l=m+1;         //如果当前分配使得分配份额大于抄写员人数,则把区间下限增大至m+1;
    76   }
    77   print(l);  // l>=r,此分配方案可行,输出
    78 }
    79 
    80 int main()
    81 {
    82     int T,t;
    83     cin>>T;
    84     t=T;
    85     while(T--)
    86     {
    87         Init();
    88         Do();
    89     }
    90     return 0;
    91 }*/


     

  • 相关阅读:
    EF单实对应多表
    阻止保存要求重新创建表的更改
    Jenkins 修改主目录正解 workspace
    JNLP文件具体说明编辑
    Jenkins新建节点,启动方式没有“通过Java Web启动代理”选项怎么办?
    Entity Framework:“无法加载指定的元数据资源
    Java环境路径配置--转载
    趣谈StateServer在Web Garden,Web Farm下的使用
    【译文】漫谈ASP.NET中的Session
    好记心不如烂笔头之JQuery学习,第四章
  • 原文地址:https://www.cnblogs.com/x512149882/p/4709304.html
Copyright © 2020-2023  润新知