您的位置:首页 > 其它

bzoj1801(递推)

2016-08-15 17:18 183 查看
链接:点击打开链接

题意:n*m的棋盘,有多少种放象棋中炮的方式,使得两两之间不能互相伤害

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const long long MOD=9999973;
const long long ex_MOD=19999947;
long long dp[105][105][105];
int main(){
long long n,m,i,j,k,ans;
while(scanf("%lld%lld",&n,&m)!=EOF){
memset(dp,0,sizeof(dp));
dp[0][0][0]=1;                          //dp[i][j][k]表示i行,j列放一个,k列放两个
for(i=1;i<=n;i++){
for(j=0;j<=m;j++){
for(k=0;k+j<=m;k++){            //不放
dp[i][j][k]=dp[i-1][j][k];
if(j>=1){                   //放一个,用来增加j
dp[i][j][k]+=dp[i-1][j-1][k]*(m-(j-1)-k);
dp[i][j][k]%=MOD;
}
if(k>=1){                   //取一个用来增加k
dp[i][j][k]+=dp[i-1][j+1][k-1]*(j+1);
dp[i][j][k]%=MOD;
}
if(j>=2){                   //放两个增加j
dp[i][j][k]+=dp[i-1][j-2][k]*(m-(j-2)-k)*(m-(j-2)-k-1)>>1;
dp[i][j][k]%=MOD;
}
if(k>=1){                   //挪一个放一个
dp[i][j][k]+=dp[i-1][j][k-1]*j*(m-(k-1)-j);
dp[i][j][k]%=MOD;
}
if(k>=2){                   //将两个j变成两个k
dp[i][j][k]+=dp[i-1][j+2][k-2]*(j+2)*(j+1)>>1;
dp[i][j][k]%=MOD;
}
}
}
}
ans=0;
for(i=0;i<=m;i++)
for(j=0;i+j<=m;j++)
ans=(ans+dp
[i][j])%MOD;
printf("%lld\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: