台阶问题

台阶问题
在这里插入图片描述
分析
第 一 眼 看 到 这 题 的 时 候 就 直 接 想 用 D f s 模 拟 走 路 的 过 程 , 可 是 发 现 n 数 据 范 围 为 1 e 5 , 就 计 算 一 下 复 杂 度 。 接 近 O ( 2 n ) 第一眼看到这题的时候就直接想用Dfs模拟走路的过程,可是发现n数据范围为1e5,就计算一下复杂度。接近O(2^n) Dfsn1e5O2n
无 非 就 是 t l e 。 但 是 为 了 练 习 我 的 d f s 模 板 , 于 是 我 就 手 打 一 遍 T l e 的 d f s , 代 码 如 下 无非就是tle。但是为了练习我的dfs模板,于是我就手打一遍Tle的dfs,代码如下 tledfsTledfs

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
ll cnt=0,n,k,p=100003;
void dfs(ll num){
	if(num==n) {cnt++;cnt=cnt%p;return ;}
	if(num>n) return ;
	for(int i=1;i<=k;i++){
		dfs(num+i);
	}
	return;
}
int main(){
    scanf("%lld%lld",&n,&k);
    dfs(0);
    cout<<cnt<<endl;
    return 0;
}
///dfs的复杂度是2^n tle

接 下 来 , 我 就 想 用 什 么 来 优 化 d f s 呢 ? d p 突 然 出 现 在 我 的 脑 海 里 面 , 分 析 一 波 d p 可 用 性 , 发 现 符 合 最 小 子 问 题 接下来,我就想用什么来优化dfs呢?dp突然出现在我的脑海里面,分析一波dp可用性,发现符合最小子问题 dfsdpdp
于 是 , 我 就 假 设 初 始 位 置 为 j , 目 标 位 置 为 i , 那 么 d p [ d i s ] 表 示 走 到 d i s 的 时 候 所 用 的 所 有 可 能 方 式 。 我 们 接 下 来 考 虑 于是,我就假设初始位置为j,目标位置为i,那么dp[dis]表示走到dis的时候所用的所有可能方式。我们接下来考虑 j,idp[dis]dis
怎 样 从 j 转 移 到 i 位 置 呢 ? 怎样从j转移到i位置呢? ji
从 j 位 置 走 到 i 位 置 , 分 j = i − k , i − ( k − 1 ) , i − ( k − 2 ) , . . . . . . , i − 1 这 些 位 置 走 一 步 到 达 , 那 么 我 们 就 可 以 利 用 循 环 来 更 新 d p [ i ] 从j位置走到i位置,分j=i-k,i-(k-1),i-(k-2),......,i-1这些位置走一步到达,那么我们就可以利用循环来更新dp[i] jij=ik,i(k1),i(k2),......,i1dp[i]

for(int i=1;i<=n;i++){
    for(int j=1;j<=k;j++){/判断条件需要修改,这里只是为了说明怎么走
        dp[i]=dp[i]+dp[i-j];
    }
}

细 心 的 你 可 以 发 现 当 i 小 与 等 于 k 的 时 候 会 出 现 错 误 。 没 错 , 就 是 这 样 , 这 里 我 们 就 可 以 在 上 面 的 判 断 条 件 中 改 一 下 细心的你可以发现当i小与等于k的时候会出现错误。没错,就是这样,这里我们就可以在上面的判断条件中改一下 ik
把 j &lt; = k 把j&lt;=k j<=k改成j<=k&&i-j>=0

AC

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int n,k,p=100003,dp[maxn];
int main(){
    scanf("%d%d",&n,&k);
    dp[0]=dp[1]=1;
    for(int i=2;i<=n;i++){
    for(int j=1;j<=k&&i-j>=0;j++){
        dp[i]=(dp[i]+dp[i-j])%p;
    }
    }
    cout<<dp[n]<<endl;
    return 0;
}


备注,ll数据处理比int数据慢很多,见下图
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值