第一部分 基础算法(第一章 递推算法)例题

这篇博客详细介绍了五个基于递推算法的例题,包括错排问题、奇怪的汉诺塔、数的划分、传球游戏和平铺方案。每个例题都给出了问题描述、输入输出格式、数据范围与提示以及解题思路,并使用递推公式阐述了解决方案。
摘要由CSDN通过智能技术生成

例题一 错排问题:link

题目描述
求多少n个数的排列 ,满足对于任意的 。

输入格式
一个整数 n。

输出格式
一个整数,表示答案。

样例
输入样例

2

输出样例

1

数据范围与提示
对于 100 100% 100 的数据, 1 < = n < = 20 1<=n<=20 1<=n<=20

思路:
设f(n)表示n个数合法的错排方案数

  1. 我们考虑第n个元素,把它放在一个位置k上,共有n-1种放法( k ≠ n k\neq n k=n,即不能放回原位)
  2. 考虑第k个元素,此时有两种:
    (1)把第k个元素放在位置n上,那么对于除n以外的n-1个元素,
    由于第k个元素以固定放在位置n上,所以剩下的n-2的数错排,即有f(n-2)种放法
    (2)不把第k个元素放在位置n上,那么对于除n以外的n-1个元素错排就行了,即f(n-1)种放法
    故有递推式:
    f ( n ) = ( n − 1 ) ( f ( n − 1 ) + f ( n − 2 ) ) n ≥ 3 f(n)=(n-1)(f(n-1)+f(n-2)) n\geq3 f(n)=(n1)(f(n1)+f(n2))n3
    边界为:
    f ( 1 ) = 0 , f ( 2 ) = 1 f(1)=0,f(2)=1 f(1)=0,f(2)=1
#include <cstdio>
#include <iostream>
#define ll long long
using namespace std;
const ll N = 25;
ll n, f[N];
int main()
{
   
	scanf("%lld", &n);
	f[1] = 0, f[2] = 1;
	for(ll i = 3; i <= n; i++) f[i] = (i - 1) * (f[i - 1] + f[i - 2]);
	printf("%lld", f[n]); 
	return 0;
}

例题二 奇怪的汉诺塔:link

题目描述:
汉诺塔问题,条件如下:
这里有 A、B、C 和 D 四座塔。
这里有 个圆盘, 的数量是恒定的。
每个圆盘的尺寸都不相同。
所有的圆盘在开始时都堆叠在塔 A 上,且圆盘尺寸从塔顶到塔底逐渐增大。
我们需要将所有的圆盘都从塔 A 转移到塔 D 上。
每次可以移动一个圆盘,当塔为空塔或者塔顶圆盘尺寸大于被移动圆盘时,可将圆盘移至这座塔上。 请你求出将所有圆盘从塔 A 移动到塔 D,所需的最小移动次数是多少。

输入格式
没有输入。

输出格式
对于每一个整数 ( 1 ≤ n ≤ 12 1\leq n\leq12 1n12),输出一个满足条件的最小移动次数,每个结果占一行。

思路:
首先我们来分析一下三根柱子的问题,
设d(n)表示三个柱子n个盘子的最优步数
先将A柱上 ( n − 1 ) (n-1) (n1)个盘子移到B柱上,那最优的步数为d(n-1),
再将A柱上剩余的1个盘子移到C柱上,那最优步数为$1 即:d(1) $
最后将B柱上的 ( n − 1 ) (n-1) (n1)个盘子移到C柱上,最优步数为 d ( n − 1 ) d(n-1) d(n1)
故有递推式:
d ( n ) = 2 × d n − 2 + 1          n > 1 d(n)=2\times d_{n-2}+1\;\;\;\;n>1 d(n)=2×d

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值