标签:特征 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