算法 —— 递推

news2025/1/13 7:22:45

目录

递推

数楼梯

斐波那契数列

一维数组递推

P1002 过河卒

二维数组递推 

P1044 栈

卡特兰数


递推

将一个很大的任务分解成规模小一些的子任务,子任务分成更小的子任务,直到遇到初始条件,最后整理归纳解决大任务的思想就是递推与递归思想,不过这两者还是有一些区别:

  • 递归:从上到下 从未知到已知解决问题
  • 递推:从下到上 从已知到未知解决问题

数楼梯


斐波那契数列

此题很像斐波那契数列的解决方式,斐波那契数列是指这样一个数列:1,1,2,3,5,8,13,21,34,55,89……这个数列从第3项开始 ,每一项都等于前两项之和。我们先看斐波那契在百度百科上的定义:

 一开始尝试用递归函数进行尝试,但是很不幸超时了:

int count_ways(int x)
{
	if (x == 1)
		return 1;
	else if (x == 2)
		return 2;
	else
		return count_ways(x - 1) + count_ways(x - 2);
}

一维数组递推

之后修改了数据类型以及计算方式,打算尝试利用递推算法:

#include<bits/stdc++.h>
using namespace std;

long long stairs[5001] = { 0 };

int main()
{
	int n; cin >> n;
	stairs[1] = 1, stairs[2] = 2;
	for (int i = 3; i <= n; i++)
		stairs[i] = stairs[i - 1] + stairs[i - 2];
	cout << stairs[n] << endl;
	return 0;
}

虽然这次没有超时,但是long long还是不够存放最大数据,很显然要利用高精度加递推解决:

轻松解决,大家对高精度感兴趣的可以看我的这篇博客:算法 —— 高精度(模拟)

接着说一下,为什么这个动态转移方程可行:

 stairs[i] = stairs[i - 1]+stairs[i - 2]

由此我们得出规律,方法数为前2次与前1次之和。 


P1002 过河卒

由于士卒只能向下或者向右走,从题目中可以得出此动态转移方程 :

f[i][j] = f[i-1][j] + f[i][j-1]

以样例6 x 6的棋盘为例,作出以下图像:

 可以看到我们把棋盘扩大了两行两列,避免出现越界访问的情况,此处越界访问共有两处:

  1. 马的坐标如果在边界,他可跳跃的点出现越界访问
  2. 动态转移方程的左、上坐标也会出现越界访问

二维数组递推 

 代码如下所示,这里用到了模拟与递推算法:

#include<bits/stdc++.h>
using namespace std;

const int fx[] = { 0, -2, -1, 1, 2, 2, 1, -1, -2 };
const int fy[] = { 0, 1, 2, 2, 1, -1, -2, -2, -1 };
//马可以走到的位置

int bx, by, hx, hy;
long long f[40][40];   //只有路的棋盘
bool s[40][40]; //只有马的棋盘
int main() {
    cin >> bx >> by >> hx >> hy;
    bx += 2; by += 2; hx += 2; hy += 2;
    //坐标+2以防越界
    f[2][1] = 1;//初始化
    for (int i = 0; i <= 8; i++) //标记不能过的点
        s[hx + fx[i]][hy + fy[i]] = 1;
    for (int i = 2; i <= bx; i++) {
        for (int j = 2; j <= by; j++) {
            if (s[i][j]) continue; // 如果被马拦住就直接跳过

            f[i][j] = f[i - 1][j] + f[i][j - 1];
        }
    }
    cout << f[bx][by] << endl;
    return 0;
}

为什么这样可行?由于士卒棋只能向下或者向右走,所以从一个对角到另外一个对角只存在两种可能情况,如下图所示:

 由图可知,动态转移方程可以表述此过程,因此方法可行。


P1044 栈

 在解决这道题之前先了解一个新概念:卡特兰数


卡特兰数

卡特兰数(英语:Catalan number),又称卡塔兰数、明安图数,是组合数学中一种常出现于各种计数问题中的数列。以比利时数学家欧仁·查理·卡特兰的名字命名。1730年,清代蒙古族数学家明安图在对三角函数幂级数的推导过程中首次发现,1774年被发表在《割圜密率捷法》。百度百科是这样定义卡特兰数的:

我们看一下卡特兰数的概述图:

如果一个点从坐标A(0,0)开始移动到坐标B(n,n),只允许向上或向右,并且存在约束条件 :路径只能在y = x以下,那么我们可以看到,如果要移动到B点,总路程为2n,左图绿色路径为刚好越过约束条件的情况,我们可以看到,绿色非法路径的突出点与橙色路径都不约而同的经过右图蓝色直线,意味着路径只要碰到蓝色直线即变成非法 

我们利用数学方法对这个图形进行分析:

 再次对非法路径进行分析可以得出以下结论:

合法路径方程为:C_{2n}^{ n} - C_{2n}^{n+1} = \frac{C_{2n}^{ n}}{n+1}此式得证。

 这时候将理论运用到实际,我们把右移看作入栈,上移看作出栈,同上出栈数始终比入栈大1才为非法,很显然这是一个卡特兰数问题,注意卡特兰数后面数据过大,long long存不下,很显然还需要结合高精度模拟。(此题给了限定范围最大为卡特兰数第18项即129644790)

#include <iostream>
using namespace std;

long long count_C(int n)
{
	long long tmp = 1; int d = n;
	for (int i = 2 * n; i > n; i--)
	{
		if (i % d == 0 && d > 1)
		{
			tmp *= (i / d); //尽可能缩小乘数
			d--;
		}
		else
			tmp *= i;
	}
	while (d > 1)
		tmp /= d--;
	return tmp;
}

int main()
{
	int n; cin >> n;
	long long ret = count_C(n);
	cout << ret / (n + 1) << endl;
	return 0;
}

感兴趣的小可爱们可以试着加上高精度解决n更大的情况。

如需科普请看这篇博客:「算法入门笔记」卡特兰数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1968584.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Kafka基本概念,工作流程介绍

1、消息队列与Kafka 1.1、Kafka简介 Kafka使用scala开发&#xff0c;支持多语言客户端&#xff08;c、java、python、go等&#xff09; Kafka最先由LinkedIn公司开发&#xff0c;之后成为Apache的顶级项目。 Kafka是一个分布式的、分区化、可复制提交的日志服务 LinkedIn使…

麒麟系统查看和修改ip

查看ip ifconfig ifconfig enp0s3 192.168.1.110

ROS中自定义头文件和源文件

今天分享一下如何在ROS中进行头文件和源文件的调用。案例是实现输出"Hello World" 本文的头文件(即.h文件)放在include/${project_name}路径下, 源文件和可执行文件则在src文件夹下 第一步&#xff1a;创建工作空间&#xff0c;创建包&#xff0c;使用vscode打开工作…

mysql高级语句的查询语句

一、排序语法&#xff0c;关键字排序 升序和降序 默认的排序方式就是升序 升序&#xff1a;ASC 降序&#xff1a;DESC 配合语法&#xff1a;order by 语法 1、升序 select * from info order by name; 根据名字升序排序&#xff0c;不需要加ASC select * from info order…

kubernetes prometheus 系列| helm 部署prometheus+grafana

一、环境准备 部署k8s集群 k8sv1.26直通车搭建 安装存储类 nfs动态供给直通车 安装helm工具 https://github.com/helm/helm/releases tar -zxvf helm-v3.5.4-linux-amd64.tar.gz sudo mv linux-amd64/helm /usr/local/bin/helm chmod ox /usr/local/bin/helm helm version二、…

day05 1.多线程基本概念 2.线程支持函数(多线程编程)

1、使用两个线程完成两个文件的拷贝&#xff0c;分支线程1拷贝前一半&#xff0c;分支线程2拷贝后一半&#xff0c;主线程回收两个分支线程的资源 #include <myhead.h>int copy_file(const char *srcfile,const char *destfile,int start,int len);struct Buff {const c…

TMGM官网中国大陆地区客户

仅限TMGM官网中国大陆地区客户且每位客户每月仅限参与一次 申请限制&#xff1a;客户完成某一档位并点击兑换礼物后&#xff0c;该活动结束。若客户继续入金达到下一个档位&#xff0c;可以获得多份该档位礼物&#xff0c;此时无法通过活动板块继续申请&#xff0c;需要联系客…

案例 —— 怪物出水

一&#xff0c;Ocean Setup 设置海洋Surface Grid&#xff08;使用Large Ocean工具架&#xff09; 调节默认Grid的大小尺寸及细分&#xff08;使用非常小尺寸来测试&#xff09;&#xff1b;调整频谱输入点的多少&#xff0c;频谱Grid Size&#xff0c;波浪方向&#xff0c;速度…

Python基础教程(三)类和对象、异常处理和模块

8.类与对象 8.1 面向对象 面向对象的三大基本特征: 封装、继承、多态。 在面向对象编程中&#xff0c;封装&#xff08;Encapsulation&#xff09;是一种将数据和操作&#xff08;方法&#xff09;组合在一起的机制。通过封装&#xff0c;我们可以隐藏数据的具体实现细节&am…

鸿蒙系统开发【设备安全服务-应用设备状态检测】安全

设备安全服务-应用设备状态检测 介绍 本示例向您介绍如何在应用中获取DeviceToken用于对应用的设备状态进行检测。 需要使用设备安全服务接口 kit.DeviceSecurityKit。 效果预览 Sample工程的配置与使用 在DevEco中配置Sample工程的步骤如下 [创建项目]及[应用]。打开Sam…

算法训练1

01背包问题 背包状态方程----动态规划 二维dp 使用 f[i][j] max(f[i-1][j] ,f[i-1][j - w[i]] v[i]); 伪代码&#xff1a; int dp[100][100]; void test6() {int n; //装备数量int m; //背包容量int v[105], w[105]; //前面空间&#xff0c;后面价值for (int i 1; i &l…

快速排序(上)

快速排序 前言 快速排序算法是最流行的排序算法,且有充足的理由,因为在大多数情况下,快速排序都是最快的。所以学习快速排序算法十分有必要。当然&#xff0c;既然它这么好&#xff0c;也就不太容易理解。 正文 Hoare版快排 快速排序是Hoare在1962年提出的一种二叉树结构的…

专业知识 | 操作系统与网络 | 3. Linux 环境基础开发工具使用

知足知不足&#xff0c;有为有不为&#xff01;——《心安即是归处》 目录 专业知识 | 操作系统与网络 | 3. Linux 环境基础开发工具使用 专业知识 | 操作系统与网络 | 3. Linux 环境基础开发工具使用

SpringDataJPA(三):多表操作,复杂查询

一、Specifications动态查询 有时我们在查询某个实体的时候&#xff0c;给定的条件是不固定的&#xff0c;这时就需要动态构建相应的查询语句&#xff0c;在Spring Data JPA中可以通过JpaSpecificationExecutor接口查询。相比JPQL,其优势是类型安全,更加的面向对象。 import …

Spring Boot 整合 Dubbo3 + Nacos 2.4.0

准备工作&#xff1a;Nacos 一、前置工作 安装Nacos&#xff0c;参考&#xff1a;Nacos 快速开始 此次安装 Nacos 最新版本&#xff1a;2.4.0 单机版 安装教程&#xff1a;Linux 安装 nacos 2.4.0-CSDN博客 二、创建配置文件 创建命名空间 新增配置文件 dubbo:application:i…

关于uniapp的vue2.x版本的路由守卫拦截方案

使用uni-read-pages和uni-simple-router实现&#xff0c;方案思路如下 首先在packge.json把下面两个依赖npm install 一下&#xff0c;我目前是这两个版本&#xff0c;别的版本号没有测试过 "dependencies": {"uni-read-pages": "^1.0.5",&quo…

matplotLib在图中标出最后一个点的值

import matplotlib.pyplot as plt import numpy as np# 生成100个随机数据 data np.random.rand(100)# 绘制数据 plt.plot(data, labelData Points)# 获取最后一个数据点的位置和值 last_x len(data) - 1 last_y data[-1]# 用红圈标出最后一个点 plt.plot(last_x, last_y, r…

《动手做科研》09. 万事具备,只欠行动

地址链接:《动手做科研》09. 万事具备&#xff0c;只欠行动 欢迎加入我的知识星球&#xff0c;定期分享AI论文干货知识&#xff01; 导读: 当你坚持学习到这一步&#xff0c;并且之前的内容都有跟着操作&#xff0c;那么恭喜你&#xff0c;你已经在脑力层面消化了最难的知识&am…

AI表情神同步!LivePortrait安装配置,一键包,使用教程

快手在AI视频这领域还真有点东西&#xff0c;视频生成工具“可灵”让大家玩得不亦乐乎。 现在又开源了一款超好玩的表情同步&#xff08;表情控制&#xff09;项目。 一看这图片&#xff0c;就知道是小视频平台出的&#xff0c;充满了娱乐性。发布没几天就已经有8000Star。 项…

7月Langchain-Chatchat 0.3.1最新 win系统-安装教程,踩坑2小时,5分钟拿去!

Win11安装 langchain-chatchat 0.3.1最新版 1. 虚拟环境安装和python包安装 conda create -n chat310 python3.10#这里很重要 需要先安装cuda版本的torch pip install torch2.3.1 torchvision0.18.1 torchaudio2.3.1 --index-url https://download.pytorch.org/whl/cu121pip…