码迷,mamicode.com
首页 > 其他好文 > 详细

P2051 [AHOI2009]中国象棋[线性DP]

时间:2019-02-10 00:15:25      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:ons   mes   www   line   bsp   象棋   amp   nbsp   ref   

最近智商有点不在线。其实一直不在线。

题目


先是想用$f[i][j][k][0/1/2]$表示摆了i行时有j列空着,k列有了一个炮,且当下摆了0/1/2个的状态,转移方程写的出来但是极其繁琐。于是又设法听取评讲者题解修改状态,最后的012完全可以删去。那么仍可以表示这一行那些列摆过1个,那些列摆过0个的种类。转移时分类即可。

$f[i][j][k]+=f[i-1][j][k]$ 什么都不摆

$f[i][j][k]+=(j+1)*f[i-1][j+1][k-1]$  摆1个炮

$f[i][j][k]+=(k+1)*f[i-1][j][k+1]$  摆1个炮

$f[i][j][k]+=(j+1)*(j+2)/2*f[i-1][j+2][k-2]$  摆两个炮,下同

$f[i][j][k]+=(k+1)*(k+2)/2*f[i-1][j][k+2]$  

$f[i][j][k]+=k*(j+1)*f[i-1][j+1][k]$

注意边界就行。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 typedef pair<int,int> pii;
 5 template<typename T>inline char MIN(T&A,T B){return A>B?A=B,1:0;}
 6 template<typename T>inline char MAX(T&A,T B){return A<B?A=B,1:0;}
 7 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
 8 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
 9 template<typename T>inline T read(T&x){
10     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c==-)f=1;
11     while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();return f?x=-x:x;
12 }
13 const int N=100+7,P=9999973;
14 int n,m,ans,f[N][N][N];
15 
16 inline void inc(int&x,int y){(x+=y)>=P?x-=P:1;}
17 
18 int main(){//freopen("tmp.in","r",stdin);freopen("tmp.out","w",stdout);
19     read(n),read(m);if(m<2){printf("%d\n",1+n+(n)*(n-1)/2);return 0;}
20     f[1][m][0]=1,f[1][m-1][1]=m,f[1][m-2][2]=m*(m-1)/2;
21     for(register int i=2;i<=n;++i)
22         for(register int j=0;j<=m;++j)
23             for(register int k=0;k<=m-j;++k){
24                 inc(f[i][j][k],f[i-1][j][k]);
25                 if(k)inc(f[i][j][k],(j+1)*f[i-1][j+1][k-1]%P);
26                 inc(f[i][j][k],(k+1)*f[i-1][j][k+1]%P);
27                 if(k>=2)inc(f[i][j][k],((j+1)*(j+2)>>1)*1ll*f[i-1][j+2][k-2]%P);
28                 inc(f[i][j][k],((k+1)*(k+2)>>1)*1ll*f[i-1][j][k+2]%P);
29                 inc(f[i][j][k],1ll*k*(j+1)*f[i-1][j+1][k]%P);
30             }
31     for(register int i=0;i<=m;++i)for(register int j=0;j<=m-i;++j)inc(ans,f[n][i][j]);
32     printf("%d\n",ans);
33     return 0;
34 }

 

P2051 [AHOI2009]中国象棋[线性DP]

标签:ons   mes   www   line   bsp   象棋   amp   nbsp   ref   

原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/10358509.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!