TC SRM498 Div1 1000PT(容斥原理+DP)

Posted czyty114

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TC SRM498 Div1 1000PT(容斥原理+DP)相关的知识,希望对你有一定的参考价值。

(Description)

网格中每步可以走((0,cdots M_x,0cdots M_y))中任意非零向量,有(K)种向量不能走,分别是((r_1,r_1),(r_2,r_2),cdots , (r_K,r_K))(r_i)一定是(10)的倍数。求从((0,0))走到((Tx,Ty))且走(R)步的方案数( (Tx,Ty,Mx,Myleq 800,Rleq 1600,Kleq 50)

无 【(Input;Sample)

无 【(Output;Sample)


【朴素做法一】

(F_{i,x,y})表示走(i)步到((x,y))的方案数

[F_{i,x,y}=sum_{a=0}^{Mx} sum_{b=0}^{My} F_{i-1,x-a,y-b} ]

[((a,b) eq ((r_1,cdots r_K,r_1,cdots r_K)) ]

状态枚举(i,x,y),状态转移枚举(a,b)

(O(1600 imes 800^4))


【朴素做法二】

在做法一的算法考虑如何优化。

我们注意到:状态转移这个东西,如果排除掉那(K)个不能走的向量,相当于对一个(Mx imes My)的矩阵求和

而这个东西是可以用二维前缀和维护的。所以我们只需枚举那(K)个不能走的向量,实现(O(K))的转移

这里我们把(K=50)这个常数忽略掉

(O(1600 imes 800^2))


【正解】

还是这个状态转移方程:

[F_{i,x,y}=sum_{a=0}^{Mx} sum_{b=0}^{My} F_{i-1,x-a,y-b} ]

我们发现:(x,y)是相互独立的,也就是说(x)轴上的转移与(y)轴上的转移是没有关系的

所以我们完全可以开两个数组:

(f_{i,x})表示在一维上走(i)步到横坐标为(x)的方案数,(g_{i,y})表示在一维上走(i)步到纵坐标为(y)的方案数

由此可得:

[F_{i,x,y}=f_{i,x} imes g_{i,y} ]

通过前缀和维护,即可(O(R imes Tx)=O(1600 imes 800))完成(DP)


这只是(K=0)的情况,如何排除那些不合法的步数?

我们设(h_{i,z})表示走(i)步全都不合法,走到((10z,10z))的方案数((r_i)一定是(10)的倍数)

[h_{i,z}=sum_{j=1}^K h_{i-1,z-r_j} ]

还有一个细节,由于((0,0))也是不合法的,那就添加一个(r_0=0)即可

这就要用到容斥原理了。

即可得到答案:

[sum_{i=0}^R sum_{z=0}^{frac{min(Tx,Ty)}{10}} (-1)^i imes h_{i,z} imes f_{R-i,Tx-10z} imes g_{R-i,Ty-10z} imes C_R^i ]

这里乘上(C_R^i)是因为我们并不知道那(i)个不合法的步是那几步

最后这个容斥的复杂度是(O(R imes frac{min(Tx,Ty)}{10})=O(1600 imes 80))

那么就做出来了

代码我就不贴了吧,因为只要想出做法,就只是一个简单的(DP)了。

主要考查的是思维

以上是关于TC SRM498 Div1 1000PT(容斥原理+DP)的主要内容,如果未能解决你的问题,请参考以下文章

[TC SRM 697 div1 lev1] DivisibleSetDiv1

[TC SRM 662 div1 lev1] FoxesOfTheRoundTable

TopCoder SRM420 Div1 500pt RedIsGood

TopCoder SRM502 Div1 1000 动态规划

SRM489 Div1 1000pts???AppleTree

topcoder srm 704 div1 -1000