BZOJ3468 : 滑雪

根据公式$x^k=\sum_{i=1}^k Stirling2(k,i)i!C(x,i)$,

设$f[i][j][k]$表示从$(i,j)$出发的所有路径的$C(路径长度,k)$的和,

根据$C(n,m)=C(n-1,m-1)+C(n-1,m)$,则有:

$f[now][k]=\sum(f[nxt][k]+f[nxt][k-1]+C(1,k))$

然后根据公式求出每种幂的答案即可。

时间复杂度$O(nmk+k^2)$。

#include<cstdio>
#include<algorithm>
const int N=305,M=N*N,P=12345;
int n,m,K,cnt,i,j,k,o,x,y,d,C[N],ans[N],fac[N],S[N][N];
int a[N][N],pos[N][N],f[2][M],dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
struct E{int x,y;E(){}E(int _x,int _y){x=_x,y=_y;}}b[M];
inline bool cmp(const E&x,const E&y){return a[x.x][x.y]<a[y.x][y.y];}
int main(){
scanf("%d%d%d",&n,&m,&K);
for(i=1;i<=n;i++)for(j=1;j<=m;j++)scanf("%d",&a[i][j]),b[++cnt]=E(i,j);
std::sort(b+1,b+cnt+1,cmp);
for(i=1;i<=cnt;i++)pos[b[i].x][b[i].y]=i;
for(k=o=0;k<=K;k++,o^=1)for(i=1;i<=cnt;i++){
f[o][i]=0;
for(d=0;d<4;d++){
x=b[i].x+dx[d],y=b[i].y+dy[d];
if(x<1||x>n||y<1||y>m||a[x][y]>=a[b[i].x][b[i].y])continue;
j=pos[x][y];
(f[o][i]+=f[o][j]+f[o^1][j]+(k<=1))%=P;
}
(C[k]+=f[o][i])%=P;
}
for(fac[1]=1,i=2;i<=K;i++)fac[i]=fac[i-1]*i%P;
for(i=1;i<=K;i++)for(S[i][i]=j=1;j<i;j++)S[i][j]=(j*S[i-1][j]+S[i-1][j-1])%P;
for(ans[0]=C[0],i=1;i<=K;i++)for(j=1;j<=i;j++)(ans[i]+=S[i][j]*fac[j]%P*C[j])%=P;
for(i=0;i<=K;i++)printf("%d\n",ans[i]);
return 0;
}

  

上一篇:Android 7.0新特性


下一篇:Android 4.0的图形硬件加速及绘制技巧