SRM 354 900pt : RooksPlacement
問題概要
N*M(N,M<50)のチェスボード上にK(<100)個のルークを配置したい。ただし全てのルークは、同じ行、列に高々1つの別のルークしか存在してはならない。可能な配置の総数を求める問題。
解法
dp[N][M][K] = (N,M,Kのときの答え)とする。このとき、最も右側の列に注目すると、最も右側にルークが0,1,2個配置されてる場合が考えられるので、それをすべて足し合わせればよい。
感想
結構シンプルに書けたと思う。
const int MOD = 1000001; typedef long long int64; int64 dp[55][55][109]; struct RooksPlacement { int countPlacements(int N, int M, int K) { for(int i=0; i<=N; i++)for(int j=0; j<=M; j++) dp[i][j][0] = 1; for(int i=0; i<=N; i++)for(int j=0; j<=M; j++)for(int k=1; k<=K; k++){ int64& cur = dp[i][j][k]; //most right no rook if(j > 0){ cur = (cur + dp[i][j-1][k])%MOD; } //most right one rook if(k >= 1 && j > 0 && i > 0){ cur = (cur + i*dp[i-1][j-1][k-1])%MOD; } if(k >= 2 && j >= 2 && i > 0){ cur = (cur + i*(j-1)*dp[i-1][j-2][k-2])%MOD; } //most right two rook if(k >= 2 && i >= 2 && j > 0){ cur = (cur + i*(i-1)/2*dp[i-2][j-1][k-2])%MOD; } } return (int) dp[N][M][K]; } };