圆邻相异,满足最小
易知如果n个勋章满足,那么n+1+1+....肯定满足
那么我们就要找到最小的满足,二分勋章颜色种数,检查是否满足,从中找到最小的可以满足的勋章数量
这里ma【i】表示第i个将军在与第i-1个将军不冲突的情况下,手中勋章与第1个将军颜色同的最多个数
mi【i】表示第i个将军在与第i-1个将军不冲突的情况下,手中勋章与第1个将军颜色同的最少个数
这样只要mi【n】=0即最后一个将军与第一个将军的勋章颜色的最小个数为0,则这个颜色种数是足够的
mi【i】=a【i】-还能最多提供与第1位将军勋章颜色不同的种数,如果还能最多提供>a【i】,即mi【i】为负数,则mi【i】=0
还能最多提供与第1位将军勋章颜色不同的种数=颜色种数-(a【i-1】+a【1】-ma【i-1】)
那ma【i】=a【1】-mi【i-1】(第1将军中除了i-1用的颜色种类其他全是第i个的),如果后者>a【i】,则为a【i】
#include<bits/stdc++.h>
using namespace std;
const int Max=3e5+10,N=2e4+10;

int ma[N],mi[N],n,a[N],l,r,mid;

bool check(int x){
	ma[1]=mi[1]=a[1];
	for(int i=2;i<=n;i++){
		ma[i]=min(a[i],a[1]-mi[i-1]);
		mi[i]=max(a[i]-(x-(a[i-1]+a[1]-ma[i-1])),0);
	}
	return mi[n]==0;
}
int  main(){
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i],l=max(l,a[i]+a[i-1]);
	r=Max;
	while(l<=r){
		mid=(l+r)>>1;
		if(check(mid)) r=mid-1;
		else l=mid+1;
	}
	cout<<l<<endl;
	return 0;
} 
这里不能像链邻相异,满足最小,求邻之和max是因为头尾可能同
3
1 2 1
max邻和=3
颜色分部 1,23,1 头尾同色