题解:
dp
方程弄出来就好做了
代码:
#include<bits/stdc++.h> const int N=505,M=1000000007; typedef int arr[N]; typedef long long ll; int n,k,c[N][N],h[N]; arr g; void add(int &x,int y){x+=y;if (x>=M)x-=M;} void dfs(int l,int r,int H,arr &ans) { memset(ans,0,sizeof(ans)); ans[0]=1; int p=l,m=r-l+1; for (int i=l;i<=r;i++) if (h[i]<h[p]) p=i; arr L,R; L[0]=R[0]=1; int h0=H;H=h[p]-H; if (l<p)dfs(l,p-1,h[p],L); if (p<r)dfs(p+1,r,h[p],R); memset(g,0,sizeof(g)); for (int i=0;i<=p-l;i++) for (int j=m;j>=i;j--) (g[j]+=(ll)ans[j-i]*L[i]%M)%=M; memcpy(ans,g,sizeof(ans)); memset(g,0,sizeof(g)); for (int i=0;i<=r-p;i++) for (int j=m;j>=i;j--) (g[j]+=(ll)ans[j-i]*R[i]%M)%=M; memcpy(ans,g,sizeof(ans)); memset(g,0,sizeof(g)); ll P=1; for (int i=0;i<=m&&i<=H;i++) { for (int j=m;j>=i;j--) (g[j]+=(ll)ans[j-i]*c[m-j+i][i]%M*P%M)%=M; P=P*(H-i)%M; } memcpy(ans,g,sizeof(ans)); } int main() { scanf("%d%d",&n,&k); for (int i=1;i<=n;i++)scanf("%d",&h[i]); c[0][0]=1; for (int i=1;i<=500;i++) { c[i][0]=1; for (int j=1;j<=i;j++) c[i][j]=(c[i-1][j]+c[i-1][j-1])%M; } arr ans; dfs(1,n,0,ans); printf("%d ",ans[k]); return 0; }