台阶问题(以C语言形式的呈递)(动态规划与DFS算法)

有 N 级台阶,你一开始在底部,每次可以向上迈 1∼K 级台阶,问到达第 N 级台阶有多少种不同方式。输入N K。输出正整数(mod 100003)为到达N阶台阶的方法。

首先对于一个编程问题我们要对其的思考要有以下几个步骤

 

目录

1  对问题的整体思考

2  思考内容的数学化转化

3  数学思想转变为编程思想的实现


动态规划方法

1 台阶问题实质就是斐波那契数列进阶(斐波那契详细请看)

https://blog.csdn.net/Guanine27/article/details/106294343https://blog.csdn.net/Guanine27/article/details/106294343

根据分类计数原理,按照最后一次上台阶的阶数分类,可为N-1次时上一阶,N-2次时上两节……最多到N-K次时上K阶,于是第N次的方法就为N-1,N-2,……,N-K次之和;此方法需要计算出每一阶的方法数

2 思考内容的数学化,写为函数的形式就是F(N)=F(N-1)+F(N-2)+……F(N-k) ;且F(1)=1

3 最后的也是最复杂的(bushi)就是编程化

本篇递推主要以循环为主

首先需要定义数组,容纳每一阶的方法数量int arr[100000];

然后初始化一下

for (i = 2; i <= N; i++) i递推自增直至为所求值N(大概的将i看成N),(第一阶仅有一种,从第二阶开始,因此i=2)

 for (j = 1; j <= K && j < i; j++) j递推自增直至为K,由于N>K,所以必须保证i>j;

接下来还需要对K和i的大小进行比较,其意义是,能否从0阶直接达到N阶,当i<=K时即可以从0阶达到目标阶(这样就多一种从0到N),否则不可(初始的值就为0)。

然后递增  arr[i] += arr[i - j];

最后不要忘记取模

主体完成大概是这样

#include <stdio.h>
int cls(int N, int K)
{
    int arr[N];//数组arr[N]表示到n有几种解法
    int i, j;
    for (i = 0; i <= N; i++)
    {
        arr[i] = 0;//初始化数组
    }
    arr[1] = 1;
    //最底层不动一种方法是循环的初始值
    for (i = 2; i <= N; i++)
    {
       
        if(i<=K)arr[i] = 1;//可从0阶到达目标阶
        for (j = 1; j <= K && j < i; j++)
        {
            arr[i] += arr[i - j];
        }
        arr[i]  %= 100003;
    }
    return arr[N];
}

而主函数便相对简单

int main()
{
    int N, K;
    int ret;
    scanf_s("%d %d", &N, &K);
    ret = cls(N, K);
    printf("%d", ret);
}

总结:因为为int类型所以可能会出现溢出的情况,是一种常用的处理台阶问题的方法



DFS算法

算法介绍具体为

https://blog.csdn.net/qq_47733361/article/details/123858318https://blog.csdn.net/qq_47733361/article/details/123858318

 

 其主要的操作位循环+回溯+计数(计数步省略了)

首先仍然定义数组,将数组的每一位元素定义为1一直到第N位,代表一次上一个台阶的那一种方式,这就是第一个if()所执行的,采用N--的方式直到N==0进入到最后的if()中对方法计数

97f31d95b62d426697610b7f1abfc2aa.png

然后向前回溯一个格(index--两次抵消第一个if里的++,回退一格),判断既不等于0也不等于K,进入else result[index]变为2 一次上两个台阶 总和不变仍为N

f44ad326a2ab4c5589ee34f082eafc43.png

index++之后指向下一位的0,判断成立进入else  计数加一 同时再往前回退一位

……

直至回退到N-K时,判断是否已经index已经为0(即判断是否到达第一步),当没有在第一步

83138e6366254b0a90602ec601aa9496.png

将K变为0;同时+K变为原来的N并指向前一位

bd1a4214c6ff4ec78671286846c6920d.png

进行判断1!=0||K,进入else中,1++,指向下一步,判断得0;

93100bdd507a42bd86943fbae37ac22c.png

进入第一个if变为0自增为1;指向下一步;

6a8fcba0190148b19e226ffc1e8cf4a3.png

……直至满足和为N

当第一个值为K时,index=0;break;

1ea789d182dd4ae98007499dcd3cefbe.png

(这里可能图有误差但第一个是K这个意思大差不差,初学也不太懂)

结束循环


#include <stdio.h>

int taiJie(int N, int K)
{
	int result[100000] = { 0 };//代表第index步走的台阶数,也就是方块中的数字
	int index = 0;//index其实指的是步数,也就是图中的方块
	int counter = 0;//用来计数
	while (1)
	{
		if (result[index] == 0) {
			result[index] = 1;
			N -= 1;
			index++;
		}
		else if (result[index] == K)
		{
			if (index == 0)break;
			result[index] = 0;
			N += K;
			index--;
		}
		else {
			result[index]++;
			N -= 1;
			index++;
		}
		if (N == 0)
		{
			counter++;
			index--;
			N += result[index];
			result[index] = 0;
			index--;
		}
	}
	return counter;
}
void main()
{
	int N,K;
	scanf("%d %d", &N, &K);
	printf("%d\n", taiJie(N, K));
}

总结 这也是很多dalao可能会想到的方法,但是计算量有点大,简单计算没问题,复杂计算可能会出现超时的情况,总而言之也是一种算法



完结撒花

                                     ❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀

❀❀❀❀❀❀❀❀❀❀❀     (   emm...排版目录还不太能用明白)      ❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀

 

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
电子数据取证(Electronic Data Discovery,简称EDD)的业务范围涵盖了以下几个方面: 1. 数据收集与保全:包括从电子设备、存储介质、云平台等收集相关数据,并采取措施确保数据的完整性和安全性,防止数据被篡改或删除。 2. 数据恢复与提取:通过技术手段恢复和提取被删除、损坏或隐藏的数据,以获取关键信息。 3. 数据分析与搜索:利用专业工具和技术对大规模的电子数据进行分析和搜索,以筛选出与案件相关的信息和证据。 4. 数据处理与重建:对收集到的电子数据进行处理、归类、整理和重建,以还原数据的原始状态,并提供可供审查和分析的形式。 5. 数据鉴定与验证:通过数字签名、哈希值等方法对电子数据进行鉴定和验证,确保数据的完整性和可信度。 6. 数据分析与可视化:利用数据分析工具和技术对电子数据进行深入分析,挖掘出隐藏的模式、关联关系等,并通过可视化手段呈现分析结果。 7. 数据报告与呈递:根据法律要求和调查需求,撰写详尽的电子数据报告,并在需要时出庭呈递相关证据。 8. 法律咨询与支持:为相关当事人提供法律咨询和支持,解答与电子数据取证相关的法律问题,并协助制定合规的数据处理政策和流程。 电子数据取证的业务范围广泛,涉及到技术、法律和调查等多个领域。专业的电子数据取证公司或专家能够提供全面的服务,以支持各种类型的法律案件、企业内部调查和安全审计等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值