1287: B304
Time Limit: 1 Sec Memory Limit: 128 MB 64bit IO Format: %lldSubmitted: 9 Accepted: 4
[ Submit][ Status][ Web Board]
Description
B304 has a special meaning to every member of WHUACM training team. In fact, it is the training room of WHUACM. Year by year, the members of the team trained there. The current team leader Xioumu is not only an ACMer but also an artist. He plans to purchase some flowers to make the training room more beautiful. There are N rows of desks in B304 and each row contains M columns. He wants to put the flowers on some of them. For each desk, there shouldn‟t be more than one flower putting on it. Xioumu doesn‟t care the total amount of the flower, even if the amount is zero. Only he cares is after he finish his work, for each row and each column, there should be odd number of flowers in total. Now he needs your help. He has already known N and M and he wants to know how many ways there are which satisfied above restriction.
Input
There are multiple test cases. Each case contains two integer numbers N and M. Technical Specification 1 <= N, M <= 100
Output
For each case, output the result in one line. Since the result may be very large, just output the result mod 1,000,000,007.
Sample Input
2 2
Sample Output
2HINT
Source
思路:看到题目应该是DP计数,但是不能一格一格来DP,只能一行一行来DP。d[i][j]表示到[1,i]行每行花朵数量均为奇数时,其中有j列的花朵数量为奇数。那么答案就是d[n][m]。状态转移方程看代码。#include<bits/stdc++.h>
using namespace std;
const int MOD=1e9+7;
typedef long long ll;
ll d[101][101];
ll c[101][101];
int main()
{
memset(c,0,sizeof c);
c[0][0]=1;
for(int i=1;i<=100;i++)
{
c[i][0]=1;
for(int j=1;j<=i;j++)c[i][j]=(c[i-1][j-1]+c[i-1][j])%MOD;
}
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(d,0,sizeof d);
for(int i=1;i<=m;i+=2)d[1][i]=c[m][i];
for(int i=1;i<n;i++)
{
for(int j=0;j<=m;j++)//表示当前有j列的花朵的数量为奇数
{
if(d[i][j]==0)continue;//此处的优化让代码勉强能过,但看别人AC花的时间貌似还能优化。
for(int k=1;k<=m;k+=2)//下一行放k朵花,k为奇数
{
for(int p=0;p<=k&&p<=j;p++)//下一行放p朵花在奇数列(即把p列花朵数量为奇数的变成偶数的),k-p朵花放在偶数列
{
if(j+k-p>m)continue;
d[i+1][j-p+k-p]+=d[i][j]*(c[m-j][k-p]*c[j][p]%MOD)%MOD;
d[i+1][j-p+k-p]%=MOD;
}
}
}
}
printf("%lld\n",d[n][m]);
}
return 0;
}