车的放置

问题描述

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

enter image description here

要在这个棋盘上放K个相互不攻击的车,也就是这K个车没有两个车在同一行,也没有两个车在同一列,问有多少种方案。同样只需要输出答案mod 100003后的结果。

输入格式

输入文件place.in的第1行为有5个非负整数a, b, c, d和k。

输出格式

输出文件place.out包括1个正整数,为答案mod 100003后的结果。

样例输入

2 2 2 2 2

样例输出

38

题解

设f[i][j]表示前i行放了j个车的方案数,显然i<=j

对于第i行,有两种情况:放车或不放车。设第i行有x个格子,如果放车,那么前i行放了j-1个车,则第i行可以放的格子数为x-(j-1),根据乘法原理,放车的方案数为f[i-1][j-1]*(x-j+1);如果第i行不放车,那么前i-1行放了j个车,方案数为f[i-1][j-1]。

当i<=b时,f[i][j]=f[i-1][j]+f[i-1][j-1]*(a-j+1)

当b<i<=b+d时,f[i][j]=(f[i-1][j]+f[i-1][j-1]*(a+c-j+1))

初始化怎么办呢?起初我让f[i][0]=1,f[1][1]=a,然而死活算不对,后来我发现只要f[i][1]的值对了,其他的值就对了,所以把f[i][1]初始化一下就行了。

#include <cstdio>
const int maxn=100003;
int a,b,c,d,n,m,f[2005][1005];
int main()
{
    int i,j,k;
    scanf("%d%d%d%d%d",&a,&b,&c,&d,&n);
    m=b+d;
    for (i=1;i<=b;i++)
      f[i][1]=a*i;
    for (i=b+1;i<=m;i++)
      f[i][1]=a*i+c*(i-b);
    for (i=2;i<=b;i++)
      for (j=2;j<=i;j++)
        f[i][j]=(f[i-1][j]+f[i-1][j-1]*(a-j+1))%maxn;
    for (i=b+1;i<=m;i++)        
      for (j=2;j<=i;j++)
        f[i][j]=(f[i-1][j]+f[i-1][j-1]*(a+c-j+1))%maxn;
    printf("%d",f[m][n]);
    return 0;    
}
原文地址:https://www.cnblogs.com/rabbit1103/p/9007385.html