codeforces div1 D题解

首先,为了统计有多少对,一个简单的方法是对于松鼠走到的每一个格子,求出猫能走的所有点的集合,然后对这些集合进行累加,就能得到我们想要的答案。

但是问题的关键是在于猫走到的集合大小怎么求出来

 

在考试的时候没有完全想出来,只想到要求出一个左右边界,对于中间的可行点,我也只是觉得和松鼠当前和前一个格子的颜色有关,但是总有很多没有想清楚。

 

考完看了别人的标准程序,发现的确是这样的。

假设松鼠上一个格子颜色为a,当前为b,且 a!= b那么在猫的这个左右边界之间不能走到的点就是那些前一个点是b,当前点是a的那些格子。

 

那么这是为什么呢,如何证明其充分必要性呢,我尝试证明一下:

 

首先可以证明,如果当前格子是a,上一个是b,那么当前这个格子必然不能走到。

假设当松鼠还在上一个格子的时候,也就是颜色为a的格子的时候。

如果猫就在当前颜色为a的格子处了,那么松鼠走了一步a,猫也不得不走,也就是说猫不能留在这个格子上。

                                

如果猫在当前颜色为a的格子前面,首先由于a!=b通过松鼠走了一步a之后,猫必然不会超过上一个格子。

然后要想在不走出b这一步(走了b,松鼠也就跟着走了),必然无法到达当前这个颜色为a的格子。

 

那么为什么其他格子都可以到达呢?

这个可以用归纳法证明。

首先一开始的时候没有前驱,所以我们弄出的左右边界之间的格子都可以走。满足条件。

 

假设松鼠在前一个格子的时候,猫的左右边界是l,r,松鼠到当前格子是,猫的左右边界是L,R

显然,R >= r ,L >= l且[r + 1, R]的格子必然都是可以走到的(不然你是怎么走到R呢)

那么我们要证明的是[L,r]这些格子除了上面的情况都可以走到

 

情况一:如果a==b

  回到松鼠的上一步,也就是说松鼠在颜色为a的那一格时,假如前面一格的颜色是c,那么[L,r]中不能走的格子就是那些前面是a,当前是c的格子

  那么通过这一步,之前在a的状态就到了后一个格子c,即上回合不能到的格子这回合都可以到了。

  对于上回合能到的格子,假如不是a,那么站着不动就行了,否则就是前进了一个,虽然看似这个位置不保,但是依然符合要求

    因为:

      1:如果这个格子就是l了,那么L必然就会等于l+1,的确不能占了,也不需要占了。

      2:如果这个格子的上一个能占到,那么可以这回合前进一步到达这个地方,还是能达到这个状态(上一个格子若是a,被动前进一步,否则,可以主动前进一步)

      3:如果这个格子的上一个不能占到,也就是说上一个是ac这个形式,但是从a明显可以到c这里来,然后再从c到当前格子。(由于a==b,a!=c,则b!=c)  

  因此,如果a==b,那么[L,r]之间所有格子均可到达。

 

情况二:如果a!=b

  和情况一大部分一样,如果当前格子不是“当前为a,上一个为b”的情况

    若c==b 

      若之前的格子不为b,那么也不会为c了,那么自然可以顺利到达当前格子

      若之前格子为b,那么当前格子必然不会为a了,既然不为a,那么老实待着不动即可

    若c!=b

      如果当前格子不为a,那么老实待着不动即可。

      否则,当前格子为a,那么之前的必然不会为b,可能为a,c两种可能,若为可到达,必然可以继续前进到达当前格子,若不能到达

        必然就是上一个为c,上上个为a,根据前面的证明,也是可以到达当前格子的

 

即可以证明。

 

累死我了,这个证明方法各种分类讨论,很是麻烦,不知道有什么更好的方法没。

 

 

转载于:https://www.cnblogs.com/lwhbbs/archive/2013/01/21/2870598.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值