题目大意:有n个人为成一个圈,其中第i个人想要r[i]种不同的礼物,相邻的两个人可以聊天,炫耀自己的礼物。如果两个相邻的人拥有同一种礼物,则双方都会很不高兴,问最少需要多少种不同的礼物才能满足所有人的需求,假设每种礼物有无限多个。
对于n==1 直接输出a[1]
对于n是偶数,找相邻两个和的最大值
对于n是奇数,现在假设有m个奖品,1号放1---a[1],2号开始的偶数号都尽量放小的
奇数都尽量放大的,尽量的意思就是避开前一个的范围就好。
于是我们二分m这个值就好
#include<bits/stdc++.h>
#define N 100005
using namespace std;
int n,a[N],rr[N],ll[N],st,ed;
int ans,l,r;
int main()
{
while (scanf("%d",&n)!=EOF && n!=0)
{
memset(a, 0, sizeof(a));
int why=0;
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
why=max(why,a[i]*3);
}
if (n==1)
{
printf("%d\n",a[1]);
continue;
}else
if (n%2==0)
{
ans=a[1]+a[n];
for (int i=2;i<=n;i++)
ans=max(ans,a[i]+a[i-1]);
printf("%d\n",ans);
}else
{
r=why+1;
l=a[1]+a[n];
for (int i=2;i<=n;i++)
l=max(l,a[i]+a[i-1]);
while (l<r)
{
int mid=(l+r)/2;
st=a[1];
ed=mid-a[1];
ll[1]=st;
rr[1]=0;
for (int i=2;i<=n;i++)
{
if (i%2==1)
{
rr[i]=min(ed-rr[i-1],a[i]);
ll[i]=a[i]-rr[i];
}else
{
ll[i]=min(st-ll[i-1],a[i]);
rr[i]=a[i]-ll[i];
}
}
if (ll[n]==0) r=mid;else l=mid+1;
}
printf("%d\n",l);
}
}
return 0;
}