标签:
Description
Input
Output
Sample Input
1 1 2 2 2 3
Sample Output
1 7 25
Hint
There are 7 possible arrangements for the second test case. They are: 11 11 11 10 11 01 10 11 01 11 01 10 10 01 Assume that a grids is ‘1‘ when it contains a jewel otherwise not.
题目大意在n*m的矩阵内每一行每一列都有钻石,问钻石分布的种类?
在n*m的矩阵中,假设每一行都存在,对于每一行设i为有i列不存在钻石,那么共有C(m,i)种排列。
对于其他的m-i列中可以放也可以不放,但是要排除全都不放的情况,得到2^(m-i) - 1种,再加上n行得到(2^(m-i)-1)^n
得到f(i) = C(m,i) * (2^(m-i)-1)^n ;
容斥原理排除多余的 f(0) - f(1) + f(2)....f(n) ;
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
#define MOD 1000000007
#define LL long long
LL c[60][60] , num[60][60] , k[60] ;
int main()
{
int i , j , n , m ;
memset(num,0,sizeof(num)) ;
for(i = 0 ; i <= 50 ; i++)
num[i][0] = num[0][i] = 1 ;
k[0] = 1 ;
for(i = 0 ; i <= 50 ; i++)
c[i][0] = 1 ;
for(i = 1 ; i <= 50 ; i++)
{
k[i] = k[i-1] * 2 ;
k[i] %= MOD ;
}
for(i = 1 ; i <= 50 ; i++)
{
for(j = 1 ; j < i ; j++)
{
c[i][j] = c[i-1][j-1] + c[i-1][j] ;
c[i][j] %= MOD ;
}
c[i][i] = 1 ;
}
while(scanf("%d %d", &n, &m) != EOF )
{
if( num[n][m] == 0 )
{
int temp = 1 ;
LL ans = 0 , s ;
for(i = 0 ; i <= m ; i++)
{
s = c[m][i] ;
for(j = 1 ; j <= n ; j++)
{
s *= ( k[m-i]-1 ) ;
s %= MOD ;
}
ans += temp * s ;
ans %= MOD ;
temp = -temp ;
}
if( ans < 0 )
ans += MOD ;
num[n][m] = num[m][n] = ans ;
}
printf("%lld\n", num[n][m]) ;
}
return 0;
}
hdu--5155Harry And Magic Box(组合数+容斥原理)
标签:
原文地址:http://blog.csdn.net/winddreams/article/details/42531461