圆邻相异,满足最小
易知如果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 头尾同色

京公网安备 11010502036488号