【算法设计与分析】长城守卫
算法2016-06-30
【题目】
【输入输出】
【源代码】
<span style="font-family:Microsoft YaHei;font-size:24px;">#include<cstdio> #include<algorithm> using namespace std; const int maxn=100010; int n,r[maxn],left[maxn],right[maxn]; //测试p个礼物是否足够 //left[i]是第i个人拿到的“左边的礼物”总数,right同样 bool test(int p) { int x=r[1],y=p-r[1]; left[1]=x; right[1]=0; for(int i=2;i<=n;i++) { if(i%2==0) { right[i]=min(y-right[i-1],r[i]);//尽量拿右边的礼物 left[i]=r[i]-right[i]; } else { left[i]=min(x-left[i-1],r[i]);//尽量拿左边的礼物 right[i]=r[i]-left[i]; } } return left[n]==0; } int main() { int n; while(scanf("%d",&n)==1&&n)//输入人数,当输入为0时停止输入 { for(int i=1;i<=n;i++) scanf("%d",&r[i]);//输入第i个人想要的礼物数 r[n+1]=r[1];//形成环的条件 int L=0,R=0; for(int i=1;i<=n;i++) L=max(L,r[i]+r[i+1]);//选出相邻的礼物组合最多的 if(n%2==1)//如果为奇数 { for(int i=1;i<=n;i++) R=max(R,r[i]*3);//设定上界 while(L<R) { int M=L+(R-L)/2;//采用二分法缩小范围 if(test(M)) R=M; else L=M+1; } } printf("%d\n",L); } return 0; } /* 3 4 2 2 5 2 2 2 2 2 5 1 1 1 1 1 0 */ </span>