UVALive 3177 长城守卫

时间:2021-12-31 03:43:37

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1178

http://7xjob4.com1.z0.glb.clouddn.com/8e1ee1ef5ea10e46ebda75b88b058f47

题意:n个人围圈,每人有不同或相同数量礼物,相邻礼物不能一样,求最少总礼物数。

思路: n是偶数:为相邻两人礼物数和的最大值;n是奇数:二分法选礼物数量,看是否可行,设第一个人礼物为前几种,编号为偶数的人尽量在前面取,奇数的人尽量在后面取,最后查看最后一人的礼物是否和第一个人的冲突。

 #include <bits/stdc++.h>
using namespace std; int n;
int r[],Left[],Right[]; int check(int p)
{
int i,j;
int x=r[],y=p-r[];
Left[]=x,Right[]=;
for(i=;i<=n;i++)
{
if(i%==)
{
Left[i]=min(x-Left[i-],r[i]);
Right[i]=r[i]-Left[i];
}
else
{
Right[i]=min(y-Right[i-],r[i]);
Left[i]=r[i]-Right[i];
}
}
if(Left[n]==)
return ;
return ;
} int main()
{
int i,j;
while(scanf("%d",&n)!=EOF && n!=)
{
for(i=;i<=n;i++)
{
scanf("%d",&r[i]);
}
if(n==)
{
printf("%d\n",r[]);
continue;
} int L=,R=;r[n+]=r[];
for(i=;i<=n;i++) L=max(L,r[i]+r[i+]);
if(n%==)
{
for(i=;i<=n;i++) R=max(R,r[i]*);
while(L<R)
{
int mid=(L+R)/;
if(check(mid))
{
R=mid;
}
else
{
L=mid+;
}
}
}
printf("%d\n",L);
}
return ;
}