题目链接

题意:

m行n列的矩形网格里放置k个相同的石子,所有石子都要用完,第一行,第一列,最后一行,最后一列都必须有棋子,一共有多少种合法的方案数。

输入T<=50,后面T行每行输入M、N、K(2<=m,n<=20)(k<=500)

输出方案数对1000007取模后的结果。

分析:

求出

第一行没有石子的方案数A

最后一行没有石子的方案数B

第一列没有石子的方案数C

最后一列没有石子的方案数D

用k个任意在网格放的方案数为S

那么只需要求S中不存在ABCD的方案数。

对此的话只需要容斥一下就能处理出来。

附上AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int t;
int m,n,k;
const int maxn=5e2+10;
const int mod=1e6+7;
int c[maxn+10][maxn+10];
void init()
{
	memset(c,0,sizeof(c));
	c[0][0]=1;
	for(int i=0;i<=maxn;i++){
		c[i][0]=c[i][i]=1;
		for(int j=1;j<i;j++)
			c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod;
	}
}
int main()
{
	init();
	cin>>t;
	for(int zz=1;zz<=t;zz++){
		cin>>n>>m>>k;
		int sum=0;
		for(int i=0;i<16;i++){
			int b=0,r=n,q=m;
			if(i&1)
				r--,b++;
			if(i&2)
				r--,b++;
			if(i&4)
				q--,b++;
			if(i&8)
				q--,b++;
			if(b&1)
				sum=(sum+mod-c[r*q][k])%mod;
			else
				sum=(sum+c[r*q][k])%mod;
		}
		cout<<"Case "<<zz<<": "<<sum<<endl;
	}
	return 0;
}