纪中生活 1.2

题目:


现有n本书,编号1,2,…,n。每本Pi页。全部分给m个抄写员。每人分到顺序连续的若干本,每本只分给一人。求一种方案,使每人分到的页数和的最大值为最小。输出这个值

输入:

第一行两个整数N,M(0<M<N<=3000)下一行N个数,表示书的页数.(Pi<=100000);

输出:

输出最佳方案的值。

样例输入

9 3100 200 300 400 500 600 700 800 900

样例输出

1700

数据范围

限制对于10%的数据,有N<=10;

对于50%的数据,有N<=500;

对于100%的数据,有N<=3000;

 

方案:

 

L为左边界,R为右边界,

(1)如果L<=R,做第二步

(2)M=(L+R)/ 2

(3)构造答案为M的方案,从后往前遵循能尽可能多抄的原则,求出所需人数X

(4)如果X<=M,执行R=M-1,否则L=M+1,转入第(1)步

最后的答案为L,该方法的时间复杂度为O(N*lg(P))。

 

code:

 

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int l=0,r=0;
 5 int mid;
 6 int n,m;
 7 int v,t;
 8 int num;
 9 int a[100001];
10 int main()
11 {
12     freopen("book.in","r",stdin);
13     freopen("book.out","w",stdout);
14     cin>>n>>m;
15     for(int i=1;i<=n;i++){
16         cin>>a[i];
17         if(l<a[i]){
18             l=a[i];
19         }    
20         else{
21             l=l;
22         }    
23         r=r+a[i];
24     }
25     while(l<=r){
26         mid=(l+r)/2;
27         num=0;
28         t=0;
29         while(num<n){
30             t++;
31             v=0;
32             while((v+a[num+1]<=mid)&&(num<n)){
33                 num++;
34                 v+=a[num];
35             }
36             if(v==0){
37                 num++;
38                 v=v+a[num];
39             }
40         }
41         if(t<=m){
42             r=mid-1;
43         }    
44         else{
45             l=mid+1;
46         }    
47     }
48     cout<<l;
49     return 0;
50 }

 正解是dp,但优化太过于复杂,于是选择了二分。(“最大值为最小”问题同常用二分)。。

posted @ 2019-08-20 16:25  とある科学の超电磁炮  阅读(174)  评论(0编辑  收藏  举报