10.15二中校内T3 方案数dp

10.15 T3 Dp

**3.棋子
(chess.cpp/c/pas)

【问题描述】

Magolor要在长方形的棋盘上放置棋子。
他有一个n*m格的棋盘,以及k种不同颜色的棋子。第i种颜色的棋子有a_i个,同样颜色的棋子没有区别。他要把这些棋子全部放到棋盘中,但是有些棋子会互相攻击。
攻击只会发生在不同颜色的棋子之间,而且只有当两个棋子位于同一行或者同一列,才能互相攻击。一个摆放方案是安全的当且仅当不存在两个能够互相攻击的棋子。
经过一个小时的尝试,Magolor找到了31415926535种摆放方案,但是,他想知道最多能摆放出多少种方案。两个方案不同当且仅当某个位置上的棋子颜色不同。

【输入格式】

第一行包含3个整数,n,m,k,分别表示棋盘的行数和列数,棋子的颜色数。
第二行包含k个用空格隔开的整数,表示每种颜色的棋子个数。

【输出格式】
共一行一个整数,表示安全的摆放方案数。由于答案可能很大,请输出答案对1e9+9取模的结果。
【输入样例1】

2 2 2
1 1

【输出样例1】

4

【样例说明】

有四种情况:

【输入样例2】

30 30 10
1 1 1 1 1 1 1 1 1 1

【输出样例2】

468830579

思路

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<set>
using namespace std;
#define ll long long
#define pb(x) push_back(x)
#define mp(a,b) make_pair(a,b)
#define fi first
#define se second
#define pr(x) cerr<<#x<<"="<<(x)<<endl
#define pri(x,lo) {cerr<<#x<<"={";for (ll ol=0;ol<=lo;ol++)cerr<<x[ol]<<",";cerr<<"}"<<endl;}
#define inf 100000000
#define md 1000000009
#define N 1000
ll n,m,s[1010],a[20],t,f[20][35][35],dp[20][35][35],ans,i,tmp,C[1010][1010];
int main()
{
	freopen("chess.in","r",stdin);
	freopen("chess.out","w",stdout);
	scanf("%lld %lld %lld",&n,&m,&t);
	for (i=1;i<=t;i++) scanf("%lld",&a[i]);
	C[0][0]=1;
	for (i=1;i<=1000;i++) 
	{
		C[i][0]=1;
		for (ll j=1;j<=1000;j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%md;
	}
	f[0][0][0]=1;
	for (i=1;i<=t;i++)
	for (ll x=1;x<=n;x++) 
	for (ll y=1;y<=m;y++)
	{
		f[i][x][y]=C[x*y][a[i]];
		for (ll l=0;l<=x;l++) 
		for (ll r=0;r<=y;r++)
		{
			if (l==0&&r==0) continue;
			tmp=f[i][x-l][y-r]*C[x][l]%md*C[y][r]%md;
			f[i][x][y]=(f[i][x][y]-tmp+md)%md;
		}
	}
	
	dp[0][0][0]=1;
	for (i=1;i<=t;i++)
	for (ll x=1;x<=n;x++) 
	for (ll y=1;y<=m;y++)
	{
		for (ll l=1;l<=x;l++) 
		for (ll r=1;r<=y;r++)
		{
			tmp=C[x][l]*C[y][r]%md*dp[i-1][x-l][y-r]%md*f[i][l][r]%md;
			dp[i][x][y]=(dp[i][x][y]+tmp)%md;
		}
	}
	
	for (ll x=1;x<=n;x++) 
	for (ll y=1;y<=m;y++) 
	ans=(ans+dp[t][x][y]*C[n][x]%md*C[m][y]%md)%md;
	printf("%lld\n",ans);pr(ans);
}

猜你喜欢

转载自blog.csdn.net/qq_42110318/article/details/83189039