有下面这样的一个网格棋盘,a,b,c,d表示了对应边长度,也就是对应格子数。

当a=b=c=d=2时,对应下面这样一个棋盘

要在这个棋盘上放K个相互不攻击的车,也就是这K个车没有两个车在同一行,也没有两个车在同一列,问有多少种方案。同样只需要输出答案mod 100003后的结果。
输入文件place.in的第1行为有5个非负整数a, b, c, d和k。
输出文件place.out包括1个正整数,为答案mod 100003后的结果。
2 2 2 2 2
38
【数据规模与约定】
对于部分数据,有b = 0;
对于部分数据,有a,b,c,d≤4。
对于100%的数据,a,b,c,d,k≤1000,且保证了至少有一种可行方案。
先把这个图像左右反转一下,这样方便dp
f[j][i]代表前j列放i个的方案;
v[j]代表第j列的高度;
f[j][i]=(f[j-1][i]+f[j-1][i-1]*(v[j]-i+1))%mo;
答案就是f[a+c][m]
代码:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=2010;
const int Mod=100003;
int f[N][N],v[N];
int a,b,c,d,m,ans;
int main () {
	scanf("%d%d%d%d%d",&a,&b,&c,&d,&m);
	for(int i=1; i<=c; i++) {
		v[i]=d;
		f[i][0]=1;
	}
	for(int i=1; i<=a; i++) {
		v[c+i]=d+b;
		f[c+i][0]=1;
	}
	f[0][0]=1;
	for(int j=1; j<=a+c; j++)
		for(int i=1; i<=m; i++)
			f[j][i]=(f[j-1][i]+f[j-1][i-1]*(v[j]-i+1))%Mod;
	printf("%d\n",f[a+c][m]);
	return 0;
}
原文:https://www.cnblogs.com/mysh/p/11318305.html