给定k-tree,且对每个结点的出边权重依次为1…k,求所有的边权重和为n的路径,且路径中有一条边权不少于d,反向dp即可。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <list>
#include <cstring>
using namespace std;
#define MAX 105
#define ll long long
#define INF 0x3f3f3f3f
#define mod 1000000007
int n, k, d;
ll dp[MAX][2];
ll makedp(int i,int j) {
if (i < 0) return 0;
if (i == 0) return j ^ 1;
if (dp[i][j] != -1) return dp[i][j];
dp[i][j] = 0;
for (int t = 1;t < d; ++t) {
if (j == 0) dp[i][j] += makedp(i - t, 0);
if (j == 1) dp[i][j] += makedp(i - t, 1);
dp[i][j] %= mod;
}
if (j == 1) for (int t = d; t <= k; ++t) dp[i][j] += makedp(i - t, 0), dp[i][j] += makedp(i - t, 1), dp[i][j] %= mod;
return dp[i][j];
}
int main()
{
freopen("a.txt", "r", stdin);
freopen("b.txt", "w", stdout);
cin >> n >> k >> d;
memset(dp, -1, sizeof(dp));
cout << makedp(n, 1) << endl;
/*for (int i = 0; i <= 3; ++i) {
for (int j = 0; j <= 1; ++j) {
cout << dp[i][j] << " ";
}
cout << endl;
}*/
return 0;
}