给你p个重塔,q个轻塔,把这些塔放在n*m的图中,这些塔会相互攻击同行同列的,轻塔不能受到攻击,重塔能承受一个塔的攻击,
问放的方法数。
先假定n < m。
可以先枚举放轻塔的个数为s,显然,方法数为C(n,s) * m * (m-1) * ... * (m-s+1) ,放完之后我们可以发现图其实缩小成为了一个(n-s)*(m-s)的图。
然后放重塔,由于重塔可以承受一个塔的攻击,dp求一下方案,令dp(i,j,k) 表示i*j的图中放k个重塔的方法,通过在图的第一行进行限定条件枚举。
可分为3个小部分:
1.第一行不放重塔 dp(i,j,k) += dp(i-1,j,k)
2.第一行放一个重塔,又分两种情况:
A:同一列不放重塔 dp(i,j,k) += j*dp(i-1,j-1,k-1)
B:同一列放重塔 dp(i,j,k) += j*(i-1)*dp(i-2,j-1,k-2)
3.第一行放两个重塔
dp(i,j,k) += C(j,2)*dp(i-1,j-2,k-2)
求出dp数组之后即总方法数为segma(0,q,i) segma(0,p,j) C(n,i)*m*...*(m-i+1)*dp(n-i,m-i,j)
由于不能不放,所以需要最后减去1.
时间复杂度为K*200^3,K为一常数。
#include
#include
#include
#include
#include
#include <set>
#include