2021/1/10 递归与递推

1.AcWing 92. 递归实现指数型枚举
在这里插入图片描述
分析:数据范围n<=15,一看就是指数型的复杂度,这种指数类型的复杂度一般就是dfs+剪枝,每个数字都有两种状态,选或者是不选,开一个数组记录状态,左分支为选了的,右分支为没选的,左右两边递归即可
画出递归搜索树
以n=3为例
在这里插入图片描述
AC代码:

#include<bits/stdc++.h>
using namespace std;
int n;
const int N=16;
int st[N];//记录状态
//0表示未考虑,1表示没选,2表示选了 
void dfs(int u)
{
	if(u>n)   //递归结束条件 
	{
		for(int i=1;i<=n;i++)
		{
			if(st[i]==2)
			cout<<i<<" ";
		}	
       cout<<endl;
	 return;
	}
	//左分支,没选的
	st[u]=1;
	dfs(u+1);
	st[u]=0;//恢复现场	
	//右分支,选了的
	st[u]=2; 
    dfs(u+1);
	st[u]=0;//恢复现场 
}
int main()
{
	cin>>n;
	dfs(1);
}

2.AcWing 94. 递归实现排列型枚举
在这里插入图片描述
分析:输出全排列,n<=9的数据范围,dfs暴力枚举每个位置可以放哪些数,开两个数组,一个数组st记录状态,即当前数字是否被使用过,另一个数组way记录这个当前位置放的数,达到递归出口条件,遍历way数组输出即可,从头开始枚举,输出来的已经是按字典序排好的了
画出递归搜索树:
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
int n;
const int N=10;
int st[N];
int way[N];
void dfs(int u)
{
	if(u>n)
	{
		for(int i=1;i<=n;i++)
		{
			cout<<way[i]<<" "; 
		}
		cout<<endl;
		return;
	}
	for(int i=1;i<=n;i++)
	{
		if(st[i]==0)
		{
			st[i]=1;
			way[u]=i;
			dfs(u+1);
			st[i]=0;//回复现场
		}
	}
}
int main()
{
	cin>>n;
	dfs(1);
}

3.dotcpp1024 母牛的故事
在这里插入图片描述
分析:今年的母牛数量=去年的母牛数量+新出生的小母牛数量
新出生的小母牛数量=前三年的母牛数量
所以递推关系式:f(n)=f(n-1)+f(n-3)
首先我想到用递归,但递归是指数级别的复杂度,一般适用于n<=30的数量范围,此题n=55,所以时间超限
dp做法:
根据递推关系式,开一个数组边算边记录下来

/*#include<bits/stdc++.h>
using namespace std;
int fun(int n)
{
    if(n<=4)
    return n;
    else 
    return fun(n-1)+fun(n-3);
}
int main()
{
	int n;
	while(cin>>n&&(n!=0))
	{
		cout<<fun(n)<<endl;
	}
}*/
//时间超限
#include<bits/stdc++.h>
using namespace std;
int cow[56]={0,1,2,3,4};
int n;
int main()
{
	for(int i=5;i<55;i++)
	{
		cow[i]=cow[i-1]+cow[i-3];
	}
	while(cin>>n&&(n!=0))
	{
		cout<<cow[n]<<endl;
	}
} 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值