1. 程式人生 > >洛谷P2051 [AHOI2009]中國象棋(動態規劃)

洛谷P2051 [AHOI2009]中國象棋(動態規劃)

dp[i][j][k]表示放了前i行,有j列是有1個棋子,有k列有兩個棋子

#include <bits/stdc++.h>
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <vector>
#include <cstdlib>
#include<map>
using namespace std;
typedef long long ll;
int n,m;
ll mod=9999973;
ll dp[110][110][110];
int main()
{
   scanf("%d%d",&n,&m);
   memset(dp,0,sizeof(dp));
   dp[0][0][0]=1;
   for(int i=1;i<=n;i++)
       for(int j=0;j<=m;j++)
           for(int k=0;k<=m-j;k++)
           {
               dp[i][j][k]+=dp[i-1][j][k];
               if(j>=1) dp[i][j][k]+=dp[i-1][j-1][k]*(m-j+1-k);//在沒有的上面加一個
               if(k>=1) dp[i][j][k]+=dp[i-1][j+1][k-1]*(j+1);//在有的上面加一個
               if(j>=2) dp[i][j][k]+=dp[i-1][j-2][k]*(m-j+2-k)*(m-j+1-k)/2;//兩個沒有的各加一個
               if(k>=1) dp[i][j][k]+=dp[i-1][j][k-1]*(m-j-k+1)*j;//一個沒有一個有一個
               if(k>=2) dp[i][j][k]+=dp[i-1][j+2][k-2]*(j+2)*(j+1)/2;
               dp[i][j][k]%=mod;
           }
   ll ans=0;
   for(int i=0;i<=m;i++)
    for(int j=0;j<=m;j++)
       {
           ans+=dp[n][i][j];
           ans%=mod;
       }
    printf("%lld\n",ans);

   return 0;
}

是有1個棋子,有k列有兩個棋子