复制代码

P2051 [AHOI2009]中国象棋

每日一题:传送门

 

题目分析: n m 放炮,导致每行列当中 仅仅有 0 1  2 这样的情况

所以 状态转移  dp[i][j][k]   ===========> 处理了 i 行 有 j 个1  ,k 个 2

  1.添加一行 0  dp[i+1][j][k]   += dp[i][j][k]

  2.添加一行1 可以新行,可以原先0 

    dp[i+1][j+1][k] += dp[i][j][k]*(m-j-k)    

  3. 添加一行2 ,从1 上添加

    dp[i+1][j-1][k+1] +=  dp[i][j][k]*j
        4.添加2行1

     dp[i+1][j+2][k]  +=  dp[i][j][k]*c(m-j-k)
        5.放两个,一个在没有棋子的列,一个在有一个棋子的列

    dp[i+1][j][k+1]  +=  dp[i][j][k]*(m-j-k)*j 

       6.两个,在一个棋子的列

      dp[i+1][j-2][k+2]+= dp[i][j][k]*c(j) 

#include<bits/stdc++.h>
using namespace std;
#define LOACL  freopen("in","r",stdin);\
         freopen("out","w",stdout); 
#define FASTIO  ios::sync_with_stdio(false);
#define CLOCK cout<<1.*clock()/CLOCKS_PER_SEC<<"ms"<<"\n";


const int   inf = 987654321;
const int    sz = (int)101 + 5;
const int   mod = 9999973;
const int sqrtn = 300; 

#define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) 
#define CLR(arr,val) memset(arr,val,sizeof(arr)) 
#define DBG(x) cout<<(#x)<<"="<<x<<endl
#define FOR(i, a, b)  for(int i=(a); i<(b); i++)
#define REP(i, a, b)  for(int i=(a); i<=(b); i++)
#define DOWN(i, a, b) for(int i=(a); i>=(b); i--)


#define all(x) x.begin(),x.end()
#define low(x) (x)&(-x)
#define pb push_back
typedef long long ll; 
typedef double dl; 

int n,m;
ll dp[sz][sz][sz];
inline int c( int num ) 
{ // 相当于C(num,2)
    return num*(num-1)/2;
}

int main()
{
    LOACL
    FASTIO
    
    cin>>n>>m;
    dp[0][0][0]=1;
     REP(i,0,n-1)REP(j,0,m)REP(k,0,m-j) if(dp[i][j][k])
    {
        dp[i+1][j][k] =(dp[i+1][j][k]+dp[i][j][k])%mod;
        if(m-j-k>=1)dp[i+1][j+1][k] = (dp[i+1][j+1][k]+dp[i][j][k]*(m-j-k))%mod;
        if(j>=1) dp[i+1][j-1][k+1] = (dp[i+1][j-1][k+1]+dp[i][j][k]*j)%mod;
        if(m-j-k>=2)dp[i+1][j+2][k] = (dp[i+1][j+2][k]+dp[i][j][k]*c(m-j-k))%mod;
        if(m-j-k>=1&&j>=1) dp[i+1][j][k+1] = (dp[i+1][j][k+1]+dp[i][j][k]*(m-j-k)*j)%mod;
        if(j>=2)dp[i+1][j-2][k+2]=(dp[i+1][j-2][k+2]+dp[i][j][k]*c(j))%mod; 
    } 
    ll ans = 0;
    REP(i,0,m) REP(j,0,m-i)ans= (ans+dp[n][i][j])%mod;
    

    cout<<ans<<endl;
    
    return 0;
}
View Code

 

 

 

 

 

 

  

posted @ 2018-03-31 18:03  pg633  阅读(151)  评论(0编辑  收藏  举报