首页 > 其他分享 >关于递归与分治

关于递归与分治

时间:2023-06-17 22:47:14浏览次数:46  
标签:return 递归 int 分治 long 关于 ans

关于递归

众所众知,递归是思想而不是算法。

从古至今,尽管人脑很高级,但好像人脑天生不适合模拟递归。

它为什么难以被理解呢?我认为是它的这种自身调用自身的方式看似简单,

但是实际上会建立一棵庞大的搜索树。人脑由于容易出错,而递归又是建立在上一层基础上的,所以可能越错越深。

那它的性质可以解决什么问题呢?

我觉得,它可以解决一些有前提,可分为多个阶段,每个阶段的状态十分明了的问题(怎么有点像dp?当然,dp可以借助递归思想来分析)

补充

同时,还可以通过搜索树的形态来看出这一点。

搜索树上每个节点为一个状态,每一个状态有且只有一个前驱,但可以扩展到多个不同的状态。那么由根节点(初态)到叶子节点(终态)的路径就是一个可能的问题解决的方案,或解决方案的形成过程

也就是说,如果一个问题可以一步一步解决,并且每一步都很相似,就可以试着递归解决。

例题

经典问题:

要把N个相同苹果放进M个不同盘子,允许空盘,共有几种不同方案

dfs大家都知道。想要不漏很简单。

那不重呢?

首先,为什么可以用dfs?
因为我们可以一个盘子一个盘子地决定放几个苹果。

然后,分析各个可行方案,例如
2 6 9 和 2 9 6

可以发现,如果两个方案排序后一样,那他们就属于同一方案。

所以我们可以控制dfs进行升序查找:

void dfs(int d,int p,int lst){
	if(d&&p>n) return;
	if(d==0||p>n){
		cnt++;
		return;
	}
	for(int i=lst;i<=d;i++){
		dfs(d-i,p+1,i);
	}
}

关于分治

分治是一种将问题划分成若干子问题,再解决子问题的一种思想。

问题
分治等于二分吗?二分是分治思想的一个应用。
二分为什么要求答案空间具有单调性?因为二分省力的关键,就在于它可以通过题目的性质而抛弃必然不可能为答案的一半。
如果没有单调性,那么就有可能抛弃掉答案,从而出错

假如一个问题可以被分为较为简单或分为最优与非最优的子问题,那么就可以使用分治思想。可见,递归与分治都涉及了“分步解决,大问题化小”的思想,因此分治可以用递归实现。

例题

经典问题:

给你三个整数 a,b,p,求 $ a^b mod p$ 其中,\(a,b,p<2^{31}\)

这么大,O(n)解决肯定不行

我们尝试划分问题,众所周知\(a^{2b}={a^b}^2\)

那么我们就只要每次把底数*底数,不就可以省去中间的步骤了吗

这就相当于,每次把问题缩小到一半,只不过是反着求解的罢了。

#include<bits/stdc++.h>
using namespace std;
long long a,b,p;
inline long long fpow(long long d,long long z,long long m)
{
	long long res=1;
	while(z>0)
	{
		if(z%2!=0) res=res*d%m;//z&1 == z%2!=0   
		d=d*d%m;
		z=z/2;//z>>=1 == z=floor(z/2) == z/2
	}
	res%=m;
	return res;
}
int main()
{
	cin>>a>>b>>p;
	cout<<a<<"^"<<b<<" mod "<<p<<"="<<fpow(a,b,p);
}

Ex

这是一个pj-,但是极端恶心的题目:
幂次方

其中,对于每一个二进制分解出的数,我们对它再进行分解,最后通过判断来合成答案。(递归)

#include<bits/stdc++.h>
using namespace std;
int n;
string ans;
int find(int &n1)
{
	int cnt=0;
	while(true)
	{
		if(pow(2,cnt+1)>n1) break;
		cnt++;
	}
	n1-=pow(2,cnt);
	return cnt;
}
void work(int idx)
{
	if(idx==1)
	{
	ans+="2";
	return;	
	} 
	if(idx==0)
	{
	ans+="2(0)";
	return;
	}
	ans+="2(";
	while(idx)
	{
	
	work(find(idx));
	if(idx) ans+="+";
	}
	ans+=")";
}
void make()
{
	while(n)
	{
		int l=find(n);
		work(l);
	//	cout<<"Debug:"<<l<<endl;
		ans+="+";
	}
	ans.pop_back();
	cout<<ans;
	return;
}
int main()
{
	cin>>n;
	make();
	return 0;
}

EOF

感谢观看。\(\huge QwQ\)

标签:return,递归,int,分治,long,关于,ans
From: https://www.cnblogs.com/haozexu/p/17488414.html

相关文章

  • 关于BFS
    BFS目录Content概述问题思考与性质典型应用优化与扩展Part1概述I.什么是BFS?广度优先搜索(breadthfirstsearch),是以同层可达状态优先,一层层向外扩展的搜索算法。一般以队列实现II.算法基本结构图源:CSDN@sigdIII.动画过程演示通常,bfs会用在遍历图,下面的图生......
  • 关于KMP
    关于KMP平凡,而又不平凡的一天,12月31日,2022年的最后一天,让我们用几句代码迎接新年的到来。cout<<"Goodbye2022\n";printf("Hello2023!");扯正题。Kmp的简介KMP算法是字符串匹配算法,基础的用途是在文本串中快速查找与模式串相匹配的位置。一些感想我们在研究这个算法的......
  • 关于最小生成树
    关于最小生成树目录概述性质Prim算法实现例P1194买礼物Kruskal算法实现思想例P4047部落划分Part1概述一个连通图的生成树是一个极小的连通子图,它包含图中全部的n个顶点,但只有构成一棵树的n-1条边。我们定义无向连通图的最小生成树(MinimumSpannin......
  • 关于单调栈
    关于单调栈目录概述实现思想例一P5788[模版]单调栈例二P4147玉蟾宫Part1概述单调栈是一种其中元素具有单调性的线性结构。由于其栈的特性,这种结构可以用来处理左边\右边比它小\大的数。实际上,作者认为,遇到题目中元素:“限制”它的左、右且被其左、右“限制”的......
  • 痞子衡嵌入式:主流QuadSPI NOR Flash厂商关于QE位与IO功能复用关联设计
    大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家讲的是几家主流QuadSPINORFlash厂商关于QE位与IO功能复用关联设计。痞子衡之前写过一篇文章《串行NORFlash下载/启动常见影响因素之QEbit》,这篇文章介绍了几家主流厂商关于QEbit在Flash内部寄存器位置以......
  • AMBA2 关于APB
    参考https://zhuanlan.zhihu.com/p/419750074https://zhuanlan.zhihu.com/p/623829190注:波形图片来自于AMBA2APBProtocolSPEC.1.APB的用处APB不支持流水线设计,不支持突发传输。APB和AHB一样,有数据总线和地址总线,读写使用PWRITE和HWRITE控制,不能同时读写数据。......
  • 关于Cookie Session 和Token,以及应用场景
    关于Cookie和Session(面试经常问)共同之处:cookie和session都是用来跟踪浏览器用户身份的会话方式。关于会话在日常生活中,从拨通电话到挂断电话之间的一连串的你问我答的过程就是一个会话。Web应用中的会话过程类似于生活中的打电话过程,它指的是一个客户端(浏览器)与Web服务器之间连......
  • 分治
    分治算法概述分而治之,称之分治。本质就是将一个大规模的问题分解为若干规模较小的相同子问题,分而治之。本质可以使用分治算法的情况——问题需要满足一下三个条件:原问题可被分解为若干规模较小的相同子问题;子问题相互独立;子问题的解可以合并为原问题的......
  • 域名解析之递归查询VS迭代查询
    【大部分内容转自中科三方】DNS解析是互联网中的重要环节,承担着将域名翻译为可由计算机直接读取的IP地址的基础功能。根据查询对象不同DNS解析可分为递归解析和迭代解析两种方式什么是递归查询?“递归解析”是最常见也是默认的一种解析方式。在这种解析方式中,如果客户端配......
  • 关于js单线程的问题
    为什么说js是单线程?为了搞清楚这个问题,我们需要先了解这几个问题:什么是线程?什么是进程?他们之间的关系?什么是任务队列(EventQueue),任务分类(宏任务、微任务)?什么是事件循环?为什么说js是单线程?为什么js要是单线程?接下来我们一起来看一下:什么是线程?什么是进程?他......