算法设计与分析复习笔记(上)

本文是作者复习算法设计与分析的笔记,涵盖了分治和动态规划两大设计技术。通过代码示例介绍了如何应用这些方法解决具体问题。
摘要由CSDN通过智能技术生成

简介:本文是博主在复习算法设计与分析的笔记,参考了北大算法设计与分析以及王晓东编著的《计算机算法设计与分析》第四版相关内容,如有错误,欢迎指正。

设计技术

分治

使用条件 规约为独立求解子问题
设计步骤 规约方法,初始子问题的计算,子问题解的综合方法,注意子问题划分均衡,类型相同
递归算法分析 求解递推方程
改进途径 减少子问题数,预处理
典型问题 二分检索,归并排序,芯片测试,幂乘,矩阵乘法,最邻近点对,多项式求值

代码

1:阶乘函数
int facorial(int n)
{
   
	if(n==0) return 1;
	return n*facorial(n-1);2:fibonacci数列
int fibonacci(int n)
{
   
	if(n<=1) return 1;
	return fibonacci(n-1)+fibonacci(n-2);
}3:排列问题
template<class Type>
void Perm(Type list[],int k,int m)
{
   
	//产生list[k,m]的所有排列
	if(k==m)
	{
   //只剩下一个元素
		for(int i-0;i<=m;i++)cout<<list[i];
		cout<<endl;
	}
	else//将list[k:m]中的每个元素分别与list[k]中的元素进行交换,
	然后递归计算list[k+1:m]的全排列
	{
   
		for(int i=k;i<=m;i++)
		{
   
			Swap(list[k],list[i]);
			Perm(list,k+1,m);
			Swap(list[k],list[i]);
		}
	}
	template<class Type>
	{
   
		inline void Swap(Type &a,Type &b)
		{
   
			Type temp=a;
			a=b;
			b=temp;
		}
	}

在这里插入图片描述

4:整数划分问题
int q(int n,int m)//n为要划分的整数,将最大加数n1<=m的划分个数记做q(n,m)
{
   
	if((n<1)||(m<1))return 0;
	if((n==1)||(m==1))return 1;
//最大加数不超过1
	if(n<m) return q(n,n);//最大加数大于n
	if(n==m)return q(n,m-1)+1;//q(n,n)=q(n,n-1)+1;1是n1=n的划分个数
	return q(n,m-1)+q(n-m,m)//假设分解6(n)的最大加数不超过3(m),这个划分个数=最大加数不超过2的划分个数(因为可能会有最大加数为1的,所以不能用n-m作为第一个参数)+最大加数是3的划分个数(把3再划分为最大加数不超过6-3=3的划分个数,即3个) 
}5:Hanoi塔问题
void hanoi(int n,int a,int b,int c)//n是圆盘个数,a,b,c表示塔座
{
   //把塔座a的圆盘移动到塔座b上,c为辅助塔座
	if(n>0)
	{
   
		hanoi(n-1,a,c,b);//把塔座a的n-1个圆盘移动到塔座c上,以塔座b为辅助塔座
		mov(a,b);//将a上编号为n的圆盘移到b上
		hanoi(n-1,c,b,a);//将塔座c的n-1个圆盘移动到塔座b上,以塔座a为辅助塔座
	}
}
分治法的基本思想
divide and conquer(P)
{
   
	if(|P|<=n0)adhoc(P);问题P的规模不超过n0时,直接解小规模问题P
	divide P into smaller subinstances P1,P2...Pk
	for(i=1;i<=k;i++)
		yi=divide and conquer(Pi);
		return merge(y1,y2,..yk);//归并解
}
6:二分搜索算法
template <class Type>
int BinarySearch(Type a[],const Type &x,int n)
{
   
	//在a[0]-a[n-1]中找x
	int left=0;int right=n-1;
	while(left<=right)
	{
   
		int middle=(left+right)/2;
		if(x==a[middle])return middle;
		if(x>a[middle]) left=middle+1;
		else right=middle-1;
	}
	return -1;7:棋盘覆盖
void ChessBoard (int tr,int tc,int dr,int dc,int size)
{
   //棋盘左上角的坐标(tr,tc),特殊方格的坐标(dr,dc),size=2^K,棋盘规格2^K*2^K
	if(size==1) return;//棋盘规格为1*1
	int t=tile++;//L型骨牌号
	s=size/2;//分割棋盘
	//覆盖左上角子棋盘
	if(dr<tr+s&&dc<tc+s)//特殊方格在此棋盘中
	ChessBoard(int tr,tc,dr,dc,s);
	else//此棋盘无特殊方格
	{
   //用t号L型骨牌覆盖右下角
		Board[tr+s-1][tc+s-1]=t;
		//覆盖其他方格
		ChessBoard(tr,tc,tr+s-1,tc+s-1,s);//以刚才L型骨牌覆盖的方格作为特殊方格进行继续覆盖
	}
	//覆盖右上角子棋盘
	if(dr<tr+s&&dc>=tc+s)
	//特殊方格在此棋盘中
		ChessBoard(tr,tc+s,dr,dc,s);
	else{
   //此棋盘中无特殊方格
		Board[tr+s-1][tc+s]=t;
		ChessBoard(tr,tc+s,tr+s-1,tc+s,s);}       
	//覆盖左下角子棋盘
	if(dr>=tr+s&&dc<tc+s)  
		ChessBoard(tr+s,tc,dr,dc,s);
    else{
   
    	Board[tr+s][tc+s-1]=t;
    	ChessBoard(tr+s,tc,tr+s,tc+s-1,s);}
    //覆盖右下角子棋盘
    if(dr>=tr+s&&dc>=tc+s)
    ChessBoard(tr+s,tc+s,dr,dc,s);
    else{
   
    	Board[tr+s][tc+s]=t;
    	ChessBoard(tr+s,tc+s,tr+s,tc+s,s);
    	}                                                                                                                                                                                                                                                                                                                                                                                      
}

左上角
在这里插入图片描述
右上角棋盘
在这里插入图片描述在这里插入图片描述

8:合并排序
template<class Type>
void MergeSort(Type a[],int left,int right)
{
   
	if(left<right){
   //至少2个元素
	int i=(left+right)/2;//取中点
	MergeSort(a,left,i);
	MergeSort(a,i+1;right);
	Merge(a,b,left,i,right);
  • 5
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值