版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37632935/article/details/84183489
题意:一颗满二叉树。每个点有k条边,边的权值为1~k,问你从root出发有多少种方案路径综合为n,且至少有一条边权值大于等于于d。
思路:我们定义状态dp[i][j][k]=1; 表示当前在第i层,当前权值和为j,k为1表示已经有大于等于k的边 ,k为0表示还没有大于等于k的边 。dp[0][0][0]=1,然后就是简单的转移了。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll dp[105][150][2];
ll mod=1e9+7;
int main()
{
ll n,d,k;
cin>>n>>k>>d;
dp[0][0][0]=1; //第i层,已经完成j,是已经有大于等于k的边
for(int i=1;i<=n;i++)
{
for(int j=0;j<=n;j++)
{
for(int k1=0;k1<j;k1++)
{
int temp=j-k1;//当前要走的边
if(temp>k) continue;
if(temp>=d)//0->1
{
dp[i][j][1]+=dp[i-1][k1][0]+dp[i-1][k1][1];dp[i][j][1]%=mod;
}
else
{
dp[i][j][0]+=dp[i-1][k1][0];dp[i][j][0]%=mod;
dp[i][j][1]+=dp[i-1][k1][1];dp[i][j][1]%=mod;
}
}
}
}
ll ans=0;
for(int i=1;i<=100;i++)
{
ans+=dp[i][n][1];
ans%=mod;
}cout<<ans<<endl;
return 0;
}