bzoj 1863 二分+递推

13 篇文章 0 订阅
9 篇文章 0 订阅

题意:n个人围成一个环,每个人要求有ai种不同颜色的勋章且与相邻的两个人不能有同种颜色的勋章,问最少准备多少种颜色

一个骗分的方法:  ans=max{a[i],a[i mod n+1]}  

其实这并不是骗分,当n是偶数的时候,这个东西就是正解 ∑(っ °Д °;)っ

好吧,正经的题解是二分,这种环的限制和左右不同的限制一般套路就是按照一个方向的顺序,贪心着从1推到n,然后判断n和1是否满足要求

那么我们就需要知道第n个人和第1个人是否有冲突的颜色

然后蒟蒻就跪了...去找网上的神犇涨姿势

我们用f[i]表示第i个人和第1个人最少冲突,g[i]表示第i个人和第1个人的最多冲突

那么只要f[n]=0 二分的mid就成立

先来解决最多的冲突g[i]

当然,一种情况是全部冲突,另一种情况就是i在不与第(i-1)人冲突的前提下能与a1产生的最大冲突(即a1中除去与第(i-1)人最小冲突)

即 g[i]=min{a[i],a[1]-f[i-1]}

再来解决最少的冲突f[i]

当然,一种情况是没有冲突,另一种情况就是在在ai中除去最多可以选择的不与a1冲突的颜色数,即求出i与1不得不冲突的颜色数。最多可以选择的不重复的颜色数为 在mid种颜色中第i个人可以用的总颜色(即mid-a[i-1])再除去在不与第(i-1)人冲突的前提下与a1的产生的最少冲突,(即a1中除去与第(i-1)人的最大冲突),

即 f[i]=max{0,a[i]-(mid-a[i-1]-(a[1]-g[i-1]))}

注意:二分的上界r=sigma(ai)即每个勋章的颜色都不一样,

           下界l=max{a[i]+a[i mod n+1]},即至少满足相邻的两个人颜色都不一样

mdzz,一开始没注意下界连样例都过不去...

var
        n,ans,l,r,mid   :longint;
        i               :longint;
        a,f,g           :array[0..20010] of longint;
function min(a,b:longint):longint;
begin
   if a<b then exit(a) else exit(b);
end;

function max(a,b:longint):longint;
begin
   if a>b then exit(a) else exit(b);
end;

function check(x:longint):boolean;
var
        i:longint;
begin
   for i:=2 to n do
   begin
      g[i]:=min(a[i],a[1]-f[i-1]);
      f[i]:=max(0,a[i]-(x-a[i-1]-(a[1]-g[i-1])));
   end;
   if f[n]=0 then exit(true) else exit(false);
end;

begin
   read(n);
   for i:=1 to n do
   begin
      read(a[i]);
      inc(r,a[i]);
   end;
   for i:=1 to n do l:=max(l,a[i]+a[i mod n+1]);
   f[1]:=a[1]; g[1]:=a[1]; ans:=maxlongint;
   while (l<=r) do
   begin
      mid:=(l+r)>>1;
      if check(mid) then
      begin
         if mid<ans then ans:=mid; r:=mid-1;
      end else l:=mid+1;
   end;
   writeln(ans);
end.
——by Eirlys



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值