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
",ans[i]);
  return 0;
}

  

原文地址:https://www.cnblogs.com/clrs97/p/5769318.html