题目描述
Problem - 431C - Codeforces
算法1
(暴力枚举) O(kn)O(kn)
枚举所有可能的路径,并记录经过的每一条边。
结算时剔除不符合要求的边。
TLE
LL dfs(int len, int step)
{
if(len == 0)
{
for(int i = 1; i <= step; i ++ )
if(path[i] >= D) {cnt ++; break;}
}
for(int i = 1; i <= K && i <= len; i ++ )
{
path[step] = i;
dfs(len - i, step + 1);
}
}
算法2
(dp + 状态机) O(n∗k)O(n∗k)
时间复杂度
状态转移方程
C++ 代码【循环写法】
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod = 1e9 + 7;
const int N = 1100;
int n, K, D;
LL dp[N][5];
void solve()
{
cin >> n >> K >> D;
dp[0][0] = 1;dp[0][1] = 1;
for(int i = 1; i <= n; i ++ )
for(int j = 1; j <= K && j <= i; j ++ )
{
if(j < D)
{
dp[i][0] += dp[i - j][0];
dp[i][0] %= mod;
dp[i][1] += dp[i - j][1];
dp[i][1] %= mod;
}
else
{
dp[i][1] += dp[i - j][0];
dp[i][1] %= mod;
dp[i][1] += dp[i - j][1];
dp[i][1] %= mod;
}
}
cout << dp[n][1] << endl;
}
nt main(){ solve();}
C++ 代码【记忆化搜索写法】
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod = 1e9 + 7;
const int N = 110;
int n, K, D;
LL dp[N][5];
LL idx, idxx;
void dfs(int i)
{
for(int j = 1; j <= K && j <= i; j ++ )
{
if(dp[i - j][1] == 0 && dp[i - j][0] == 0) dfs(i - j);
if(j < D)
{
dp[i][0] += dp[i - j][0];
dp[i][0] %= mod;
dp[i][1] += dp[i - j][1];
dp[i][1] %= mod;
}
else
{
dp[i][1] += dp[i - j][0];
dp[i][1] %= mod;
dp[i][1] += dp[i - j][1];
dp[i][1] %= mod;
}
}
}
void solve()
{
cin >> n >> K >> D;
//dp[0][1] = 1;
dp[0][0] = 1;
dfs(n);
cout << dp[n][1] << endl;
}
int main(){ solve();}