题目描述
恶梦是一个登山爱好者,今天他来到了黄山。
俗话说的好,不走回头路。所以在黄山,你只能往前走,或者往上走。并且很显然的是,当你走到山脊的时候,你不能够往上走,你只能往前走一步再往上走。
抽象一点而言就是,你可以把黄山视为一个N * N格点图,恶梦从(0,0)开始出发,要走到(N,N)。当他走到位置(x,y)的时候,它可以往(x + 1,y),或(x,y+1)走。
并且当他走到(x,x)的时候,由于他已经处在了山脊上,所以他不能够往(x,x+1)方向上走。
当恶梦兴致勃勃准备开始爬山的时候,他的同伴告诉他,黄山由于年久失修,有一些位置出现了大坑,不能走。恶梦觉得更刺激了,但他想先知道他能有多少种方式走到黄山顶。
由于这个数字很大,所以你只需要将答案对10^9 + 7取模输出即可。
对于30%的数据,保证N<=5000
对于另外20%的数据,保证C=0
对于另外20%的数据,保证C=1
对于100%的数据,保证N<=100000,C<=1000
保证对于(0,0),(N,N)不存在障碍点。
解题思路
如果没有山脊的限制就十分简单了嘛。
假如没有,设f[i]表示恰好走到第i个障碍点的合法路径条数,即除了这个点,路径其他点碰不到障碍。然后f[i]可以由能够到达他的障碍点j的f[j]容斥出来,即在不合法路径经过的第一个障碍点j处容斥掉不合法答案。
考虑有山脊的限制怎么办。实际上,我们如果要从(a,b)到达(c,d),不碰到直线到(c,d)的方案数=随便走到(c,d)的方案数-随便走到(c,d)关于直线的对称点的方案数。
可以发现,任意一条走到对称点的路径一定会碰到直线,其第一个碰到直线的点后面的路径对称回去,恰好一一对应不合法的到(c,d)的路径。
那么就很好算了。
代码
不是同一道题,不过大体一样,多了一些删去没用的障碍点的操作。
#include<cstdio>