组合数学 车的放置
题目描述
有下面这样的一个网格棋盘,a,b,c,d表示了对应边长度,也就是对应格子数。
当a=b=c=d=2时,对应下面这样一个棋盘。
要在这个棋盘上放K个互不攻击的车,也就是这K个车没有两个车在同一行,也没有两个车在同一列,问有多少种方案。同样只需要输出答案mod 100003 的结果
输入
输入文件的第一行为有5个非负整数a,b,c,d和K
输出
输出文件包括一个正整数,为答案 mod 100003 后的结果
样例输入
2 2 2 2 2
样例输出
38
提示
对于部分数据 ,有 b=0;
对于部分数据,有 a,b,c,d <= 4;
对于100%的数据,a,b,c,d,K <= 2000,且保证至少有一种可行方案
题解:
我先把这个图像左右反转一下
f[j][i]代表前j列放i个的方案,递推式为 f[i][j]=(f[i-1][j]+f[i-1][j-1]*(v[i]-j+1))%mod
答案为f[a+c][k];
#include <cstdio>
#include <iostream>
#include <cctype>
#define mod 100003
using namespace std;
int f[2010][2010],v[2010];
inline void read(int &x)
{
int s=0,w=1;
char c=getchar();
while(!isdigit(c)){if(c=='-')w=-1;c=getchar();}
while(isdigit(c)){s=(s<<3)+(s<<1)+c-'0',c=getchar();}
x=s*w;
}
int main()
{
int a,b,c,d,k,i,j;
read(a),read(b),read(c),read(d),read(k);
for(i=1;i<=c;i++)v[i]=d,f[i][0]=1;
for(i=c+1;i<=c+a;i++)v[i]=d+b,f[i][0]=1;
f[0][0]=1;
for(i=1;i<=a+c;i++){
for(j=1;j<=k;j++){
f[i][j]=(f[i-1][j]+f[i-1][j-1]*(v[i]-j+1))%mod;
}
}
printf("%d\n",f[a+c][k]);
}