递归算法 / 动态规划 (C语言)

递归算法:

1. 一切循环都可以写成递归
2. 数列的前一二项一般是递归出口
3. 递归函数先写递归出口,再else


斐波那契数列 Fibonacci Sequence

斐波那契数列 Fibonacci sequence 递归解法
序号:1   2   3   4    5   6    7     8  …
数列:1   1   2   3    5   8   13   21 …
表达式:
f ( n ) = { 1 ,   n  =1或2(递归出口) 3 n + 1 ,  其他 f(n) = \begin{cases} 1 , & \text{ $n$ =1或2(递归出口)} \\ 3n+1, & \text{ 其他} \end{cases} f(n)={1,3n+1, n =12(递归出口) 其他


# include <stdio.h>
# include <stdlib.h>

int f(int n);  // 递归函数

int main() {

	int n = f(8);
	printf("n = %d\n", n);

	return 0;
}

int f(int n) {

	if (n == 1) {         // 先写递归出口
		return 1;
	} else if (n == 2) {  // 先写递归出口
		return 1;
	} else {
		return (f(n - 1) + f(n - 2));
	}

}

for循环改递归

求前n项和
f ( n ) = 1 + 2 + 3 + 4 + 5 + . . . + n f(n)=1+2+3+4+5+...+n f(n)=1+2+3+4+5+...+n
f ( 100 ) = 1 + 2 + 3 + 4 + 5 + . . . + 100 = 5050 f(100)=1+2+3+4+5+...+100=5050 f(100)=1+2+3+4+5+...+100=5050


# include <stdio.h>
# include <stdlib.h>

int f1(int n);  // for循环
int f2(int n);  // 递归 递归关系: f(n)=f(n-1)+n, 出口 f(1)=1

int main() {

	int sum1, sum2, n;
	printf("请输入n:\n");
	scanf("%d", &n);
	sum1 = f1(n);
	printf("循环 sum = %d\n", sum1);

	sum2 = f2(n);
	printf("循环 sum = %d\n", sum2);

	return 0;
}

int f1(int n) {

	int s = 0;
	int i;
	for (i = 1; i <= n; i++) {
		s += i;
	}

	return s;
}

int f2(int n) {

	if (n == 1) {  // 先写递归出口
		return 1;
	} else {
		return (f2(n - 1) + n);
	}
}



动态规划:

1. 从最后一个往前选
2. 每次有两个选择:选,不选
3. 一直倒着往前,第一个是出口


求数组的前n项和(递归写法)

求数组的前n项和
{ s u m ( a r r , n ) = s u m ( a r r , n − 1 ) + a r r [ n ] s u m ( a r r , 0 ) = a r r [ 0 ] 数组第一项,递归出口 \begin{cases} sum(arr,n) =sum(arr,n-1) + arr[n] \\ sum(arr,0) = arr[0] & \text{数组第一项,递归出口} \end{cases} {sum(arr,n)=sum(arr,n1)+arr[n]sum(arr,0)=arr[0]数组第一项,递归出口


# include <stdio.h>
# include <stdlib.h>

int sum(int arr[], int m);  // 求数组的前 n 项和

int main() {

	// 求数组的前n项
	int arr[10] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
	int s = sum(arr, 8);
	printf("s = %d\n", s);

	return 0;
}

int sum(int arr[], int n) {

	if (n == 0) {  // 出口
		return arr[0];
	} else {
		return sum(arr, n - 1) + arr[n];
	}
}

求数组的前n项最大值(递归写法)

求数组的前n项最大值
{ m a x ( a r r , n ) = m a x ( m a x ( a r r , n − 1 ) , a r r [ n ] ) m a x ( a r r , 0 ) = a r r [ 0 ] 数组第一项,递归出口 \begin{cases} max(arr,n)=max{( max(arr,n-1) , arr[n])}\\ max(arr,0) = arr[0] & \text{数组第一项,递归出口} \end{cases} {max(arr,n)=max(max(arr,n1),arr[n])max(arr,0)=arr[0]数组第一项,递归出口


# include <stdio.h>
# include <stdlib.h>

int max(int arr[], int m);  // 求数组的前 n 项最大值

int main() {

	// 求数组最大值
	int l = max(arr, 8);
	printf("max = %d\n", l);

	return 0;
}

int max(int arr[], int n) {

	if (n == 0) {     // 出口
		return arr[0];
	} else {
		if (max(arr, n - 1) > arr[n]) {
			return max(arr, n - 1);
		} else {
			return arr[n];
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值