Codeforces 247-C. k - tree (dp + 状态机【for循环/记忆化搜索两种写法】)

题目描述
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();}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值