题目:
现有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,但优化太过于复杂,于是选择了二分。(“最大值为最小”问题同常用二分)。。