알고리즘 설계 및 분석 --- 재귀 및 분할 및 정복

알고리즘 설계 및 분석-재귀 및 분할 및 정복 (지속적인 업데이트 ... 아무도보고 있지 않지만 hhh)

개념 분할 및 정복 : 대규모 문제를 여러 개의 소규모 문제로 분해하여 하나씩 분할, 즉 분할 정복!
재귀의 개념 : 직접 또는 간접적으로 자신을 호출하는 알고리즘이 재귀 적이됩니다.

둘 사이의 상관 관계가 매우 강하기 때문에 교과서에서는이 두 알고리즘을 한 장에 넣습니다.

질문 1, 출력이 모두 정렬되어 있습니다 (출력의 크기가 아니라 역 추적없이 재귀를 사용해야 함).

입력 :
양의 정수를 입력합니다 (너무 크지 않습니다. 재귀 레이어의 수가 너무 크면 재귀 레이어가 시간 초과됩니다 !!!)
출력 :
1 ---- n input_case 의 전체 배열을 출력합니다
.

3

출력 _ 케이스 :

123
132
213
231
321
312

아이디어 :
재귀는 좋은 재귀 경계와 재귀 관계를 찾아야합니다! ! !
함수 P 설정 (int * a, int k, int n);

k는 0부터 계산을 시작하고 k가 문제의 경계에 도달하면 출력합니다 .k가 경계에 도달
하지 않으면 각 요소를 접두사로 사용하여 재귀 적으로 출력 합니다!
암호:

//输出全排列(递归实现)---非顺序输出 
#include<stdio.h>
using namespace std;

template<class T>
inline void swap(T &t1,T &t2){
    
    
	T temp=t1;
	t1=t2;
	t2=temp;
	return ;
}

void P(int *a,int k,int n)
{
    
    
	if(k==n){
    
    
		for(int i=0;i<n;i++){
    
    
			printf("%d",a[i]);
		}
		printf("\n");
		return ;
	}else{
    
    
		for(int i=k;i<n;i++){
    
    
			swap(a[k],a[i]);
			P(a,k+1,n);
			swap(a[k],a[i]);
		}
	}
	return ;
}

int main(){
    
    
	int n;
	scanf("%d",&n);
	int a[n];
	for(int i=1;i<=n;i++){
    
    
		a[i-1]=i; 
	}
	P(a,0,n);
	return 0;
}

문제 2, 하노이 타워 문제

문제 설명 :
3 개의 타워 a, b, c가 있습니다. a에는 n 개의 플레이트가 있으며 작은 것부터 큰 것까지 순서대로 나열됩니다
. n 개의 플레이트를 a에서 c로
이동 합니다. 참고 : 큰 플레이트는 작은 접시; 하나만 움직일 수 있음 접시 하나;
입력 :
너무 크지 않은 문제의 척도를 나타내는 양의 정수를 입력하십시오!
출력 :
출력 문제의 이동 과정 : (이 방식으로 출력)
% c-> % c \ n
최종 출력이 이동 한 횟수 : (양의 정수)
Input_case :

3

출력 _ 케이스 :

A->C
A->B
C->B
A->C
B->A
B->C
A->C
cnt=7

아이디어 :
직접 해결할 수없는 대규모 문제는 작은 문제로 나누세요 (아이디어를 나누고 정복하세요)!
암호:

#include<stdio.h>

void hanoi(int n,char x,char y,char z);
int cnt=0;
int main(){
    
    
	int n;
	scanf("%d",&n);
	hanoi(n,'A','B','C');
	printf("cnt=%d",cnt);
	return 0;
} 
void hanoi(int n,char x,char y,char z){
    
    
	if(n==1){
    
    //递归边界 
		printf("%c->%c\n",x,z);cnt++;
	}else{
    
    //如果不是边界就一直递归调用 
	hanoi(n-1,x,z,y);//将x借助z移到y 
	printf("%c->%c\n",x,z);//输出路径 
	cnt++;
	hanoi(n-1,y,x,z);//将x借助y移到z 
    }
}

질문 3, 이진 검색

문제 설명 :
어레이 A의 [0 ... N-1], 소형 ~ 대형의 정렬 된 것으로,
값 X 여기서 첨자를 찾아,
출력 NULL을 찾을 수없는 경우,
입력 :
입력은 양의 정수, N을,
그때 입력 n 양의 정수 (작은 것에서 큰 것까지);
입력에서 찾을 값 x;
출력 :
출력 x는 배열의 첨자에 해당합니다
.x가 없으면 NULL을 출력합니다.
input_case :

5
1 3 4 6 8
6

출력 _ 케이스 :

3

암호:

#include<stdio.h>

int search(int *a,int low,int high,int x){
    
    
	int mid=(low+high)/2;
	if(low==high&&a[mid]!=x)return -1;//没有找到 
	if(a[mid]==x){
    
    //找到了输出mid 
		return mid;
	}else if(a[mid]>x){
    
    //从左侧找 
		return search(a,low,mid,x);
	}else{
    
    //从右侧找 
		return search(a,mid+1,high,x);
	}
}

int main(){
    
    
	int n;
	scanf("%d",&n);
	
	int a[n];
	for(int i=0;i<n;i++){
    
    
		scanf("%d",&a[i]);
	}
	
	int x;
	scanf("%d",&x);
	int ans=search(a,0,n-1,x);
	if(ans>=0){
    
    
		printf("%d",ans);
	}else{
    
    
		printf("NULL");
	}
	return 0;
} 

시간 복잡도 : O (logn);

질문 4, 큰 정수의 곱셈 (분석)

문제 설명 :
두 개의 매우 큰 양의 정수 (이진 형식으로 제공됨)가 어떻게 시간 복잡성을 줄일 수 있습니까?
분석:
여기에 사진 설명 삽입

여기에 사진 설명 삽입
여기에 사진 설명 삽입
시간 복잡도 : from O (n ^ 2) ------> O (n ^ 1.59)

질문 5, Strassen 행렬 곱셈 (분석)

문제 설명 :
nXn 정사각형 행렬 A에 nXn 정책 B를 곱하여 nXn 정책 C를 형성합니다 .O
(n ^ 3)의 시간 복잡성
을 줄이는 방법은 무엇입니까?
분석 :
nXn 행렬을 4 (n / 2) X (n / 2) 행렬로 나눕니다. 따라서 시간 복잡도는 다음과 같습니다.
여기에 사진 설명 삽입
여기에 사진 설명 삽입
시간 복잡도 : O (n ^ 3) --------> O (n ^ 2.81 )

추천

출처blog.csdn.net/timelessx_x/article/details/115252906