道路建造

版权声明:未经过同意不得转载 https://blog.csdn.net/qq_42500298/article/details/88429327

在这里插入图片描述
在这里插入图片描述我们注意到一定会存在d1=0,dn=k。对于di>k的值,我们不关心它到底是多少,可以直接用k+1表示。
对于2~n-1的点,我们也不需要它们具体的最短路是多少。我们只需要知道对于最短路是j的点的个数就可以了。
这样我们就可以从小到大枚举所有点的最短路x,再枚举满足最短路是x的点的个数,并计算方案总数,就可以啦。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define mod 1000000007
int n;
int f[3000],g[3000];
int c[2500][2500];
int p(int a,int n)
{
    if(!n)
  return 1;
    if(n%2)
  return p(a*a%mod,n/2)*a%mod;
    return p(a*a%mod,n/2)%mod;
}
signed main()
{
    cin>>n;
    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]+c[i-1][j-1])%mod;
     }
    }
    g[1]=1;
    f[1]=1;
    for(int i=2;i<=n;i++)
        g[i]=p(2,c[i-1][2]);
    for(int i=2;i<=n;i++)
    {
        f[i]=g[i];
        for(int j=1;j<i;j++)
        {
            f[i]-=f[j]*g[i-j]%mod*c[i-1][j-1]%mod;
            while(f[i]<0)
    f[i]+=mod;
            f[i]%=mod;
        }
    }
    int ans=f[n]*c[n][2]%mod;
    cout<<ans<<endl;
 return 0; 
}

猜你喜欢

转载自blog.csdn.net/qq_42500298/article/details/88429327