竟然用二分,真是想不到;
偶数的情况很容易想到;不过奇数的就难了;
奇数的情况下,一个从后向前拿,一个从前向后拿的分配方法实在太妙了!
注:
白书上的代码有一点点错误
代码:
1 #include<cstdio> 2 #define maxn 100009 3 #include<algorithm> 4 using namespace std; 5 6 int p[maxn],right[maxn],left[maxn],n; 7 8 bool check(int m) 9 { 10 int x=p[1],y=m-p[1]; 11 left[1]=x;right[1]=0; 12 for(int i=2;i<=n;i++) 13 { 14 if(i&1) 15 { 16 right[i]=min(y-right[i-1],p[i]); 17 left[i]=p[i]-right[i]; 18 } 19 else 20 { 21 left[i]=min(x-left[i-1],p[i]); 22 right[i]=p[i]-left[i]; 23 } 24 } 25 return left[n]==0; 26 } 27 28 int main() 29 { 30 while(scanf("%d",&n)&&n) 31 { 32 for(int i=1;i<=n;i++)scanf("%d",&p[i]); 33 p[n+1]=p[1]; 34 if(n==1){printf("%d ",p[1]);continue;} 35 int l=0,r=0; 36 for(int i=1;i<=n;i++)l=max(l,p[i]+p[i+1]); 37 if(n&1) 38 { 39 for(int i=1;i<=n;i++)r=max(r,p[i]*3); 40 while(l<r) 41 { 42 int mid=(l+r)>>1; 43 if(check(mid))r=mid; 44 else l=mid+1; 45 } 46 } 47 printf("%d ",l); 48 } 49 return 0; 50 }