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 动态规划