标签:特征 div ble input 包含 log 棋盘 ret memory
除了在3个格子中都放满炮的的情况外,其它的都可以.
100%的数据中N,M不超过100
50%的数据中,N,M至少有一个数不超过8
30%的数据中,N,M均不超过6
思路{
在DP过程中发现问题的一些限制,特征,能够找到问题的突破口.
比如此题:发现每行每列都不能放超过2个棋子,那么我们从上述限制设转移方程,
f[i][j][k]为到第i行有j列放1个,k列放2个.
仔细考虑清楚各种情况算组合数转移.
}
#include<bits/stdc++.h> #define RG register #define il inline #define N 200 #define mod 9999973 #define LL long long using namespace std; LL dp[N][N][N];int n,m; LL c(int x){return (x*(x-1))/2;} void update(LL & x){x%=mod;} int main(){ scanf("%d%d",&n,&m); dp[0][0][0]=1; for(int i=0;i<n;++i){ for(int j=0;j<=m;++j) for(int k=0;k+j<=m;++k){ dp[i+1][j][k]+=dp[i][j][k];update(dp[i+1][j][k]); if(m-j-k>0){ dp[i+1][j+1][k]+=dp[i][j][k]*(m-j-k); update(dp[i+1][j+1][k]);//放一个在空位上 } if(j){ dp[i+1][j-1][k+1]+=dp[i][j][k]*j; update(dp[i+1][j-1][k+1]);//放一个在已经放过的上 } if(m-j-k>0){ dp[i+1][j+2][k]+=dp[i][j][k]*c(m-j-k); update(dp[i+1][j+2][k]);//放两个在空位上 } if(m-j-k>0){ dp[i+1][j][k+1]+=dp[i][j][k]*(m-j-k)*j; update(dp[i+1][j][k+1]);//2.1个空1个已放1 } if(j>1){ dp[i+1][j-2][k+2]+=dp[i][j][k]*c(j); update(dp[i+1][j-2][k+2]);//2.都在1 } } }LL Ans(0); for(int i=0;i<=m;++i) for(int j=0;i+j<=m;++j)Ans+=dp[n][i][j],Ans%=mod; cout<<Ans; return 0; }
BZOJ1801: [Ahoi2009]chess 中国象棋
标签:特征 div ble input 包含 log 棋盘 ret memory
原文地址:http://www.cnblogs.com/zzmmm/p/7476461.html