洛咕 P2467 [SDOI2010]地精部落
阿新 • • 發佈:2018-11-10
同波浪,簡單dp。
高度從1到n插入山脈,設f[i][j][k]表示插入了i個山脈,組成了j段,邊界上有k個山脈的方案數。
那麼新插入的山脈只會:插入在邊界上且自己是一段、插入在邊界上且與最左邊的段相連、不在邊界上且自己是一段、不在邊界上且連線兩段。
大力討論即可
// luogu-judger-enable-o2 #include<bits/stdc++.h> #define il inline #define vd void typedef long long ll; il int gi(){ int x=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-')f=-1; ch=getchar(); } while(isdigit(ch))x=x*10+ch-'0',ch=getchar(); return x*f; } int f[4201][4201][3];// 插入了i個山,有j段 int main(){ #ifndef ONLINE_JUDGE freopen("2467.in","r",stdin); freopen("2467.out","w",stdout); #endif int n=gi(),p=gi(); f[0][0][0]=1; for(int i=0;i<n;++i) for(int j=0;j<=i;++j) for(int k=0;k<3;++k){ if(!f[i][j][k])continue; if(k^2){ f[i+1][j+1][k+1]=(f[i+1][j+1][k+1]+1ll*f[i][j][k]*(2-k))%p; f[i+1][j][k+1]=(f[i+1][j][k+1]+1ll*f[i][j][k]*(2-k))%p; } f[i+1][j+1][k]=(f[i+1][j+1][k]+1ll*f[i][j][k]*(j+1-k))%p; f[i+1][j-1][k]=(f[i+1][j-1][k]+1ll*f[i][j][k]*(j-1))%p; } printf("%d\n",f[n][1][2]); return 0; }