[分层图 DP] HihoCoder #1147 时空阵

来源:互联网 发布:百度首页源码下载 编辑:程序博客网 时间:2024/05/07 10:22

题解:http://blog.csdn.net/nlj1999/article/details/50413427?locationNum=4


由于K<=100,所以构造分层图。

于是乎边只能和上一层以及本层的节点相连。

注意最后一层必有n 然后剩下的弄成一团 无所谓分不分层 放在n那一层的后面 



#include<cstdio>#include<cstdlib>#include<algorithm>using namespace std;typedef long long ll;const int P=1e9+7;const int N=105;inline ll Pow(ll a,int b){  ll ret=1;  for (;b;b>>=1,a=a*a%P)    if (b&1)      ret=ret*a%P;  return ret;}int n,K;ll C[N][N],pow2[N*N];inline void Pre(){  C[0][0]=1;  for (int i=1;i<=n;i++){    C[i][0]=1;    for (int j=1;j<=i;j++)      C[i][j]=(C[i-1][j-1]+C[i-1][j])%P;  }  pow2[0]=1;  for (int i=1;i<=n*n;i++)    pow2[i]=pow2[i-1]*2%P;}ll f[N][N][N];int main(){  freopen("t.in","r",stdin);  freopen("t.out","w",stdout);  scanf("%d%d",&n,&K); Pre();  f[0][1][1]=1;  ll Ans=0;  for (int i=1;i<=K;i++)    for (int j=i+1;j<=n-K+i;j++)      for (int k=1;k<=j-i;k++){ll tem=i==K?C[n-j+k-1][k-1]:C[n-j+k-1][k];for (int x=1;x<=j-k-i+1;x++)  (f[i][j][k]+=f[i-1][j-k][x]*tem%P*Pow(pow2[x]-1+P,k)%P*pow2[C[k][2]])%=P;if (i==K)  (Ans+=f[i][j][k]*pow2[k*(n-j)+(n-j)*(n-j-1)/2]%P)%=P;      }  printf("%lld\n",Ans);  return 0;}


0 0