Projeto e análise de algoritmo - recursão e divisão e conquista (atualização contínua ... Embora ninguém esteja observando, hhh)
Conceito de dividir e conquistar: decompor um problema de grande escala em vários problemas de pequena escala para dividi-los um a um, ou seja, dividir e conquistar!
O conceito de recursão: um algoritmo que se chama direta ou indiretamente torna-se recursivo.
A correlação entre os dois é muito forte, e é por isso que o livro coloca esses dois algoritmos em um capítulo.
Questão um, a saída está toda organizada (não de acordo com o tamanho da saída, é necessário usar recursão sem retrocesso)
entrada:
Insira um número inteiro positivo (não muito grande, a camada de recursão atingirá o tempo limite se o número de camadas recursivas for um pouco grande demais !!!)
saída: produza
a matriz completa de 1 ---- n
input_case:
3
output_case:
123
132
213
231
321
312
Idéia: A
recursão deve encontrar um bom limite de recursão e relacionamento de recursão! ! !
Defina a função P (int * a, int k, int n);
k começa a contar a partir de 0 e dá saída quando k atinge o limite do problema; quando
k não atinge o limite, ele dá saída recursivamente com cada elemento como um prefixo!
código:
//输出全排列(递归实现)---非顺序输出
#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;
}
Problema dois, o problema da Torre de Hanói
Descrição do problema:
Existem três torres a, b e c. Existem n placas em a, que são listadas em ordem de pequeno a grande
.
Mova as n placas de a para c. Observação: a placa grande não pode ser pressionada contra o prato pequeno; apenas um pode se mover Um prato;
entrada:
Insira um número inteiro positivo, que representa a escala do problema, não muito grande!
saída:
O processo de movimentação do problema de saída: (saída desta forma)
% c ->% c \ nQuantas
vezes a saída final se moveu: (número inteiro positivo)
Input_case:
3
output_case:
A->C
A->B
C->B
A->C
B->A
B->C
A->C
cnt=7
Idéia:
Para problemas de grande escala que não podem ser resolvidos diretamente, divida-os em problemas de pequena escala (divida e conquiste idéias)!
código:
#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
}
}
Pergunta três, pesquisa binária
Descrição do problema:
Para a matriz a [0 ... n-1] que foi classificada de pequeno a grande;
encontre o subscrito onde o valor é x;
se não, encontre a saída NULL;
entrada:
insira um inteiro positivo n;
então entrada n Número inteiro positivo (de pequeno a grande);
o valor x a ser encontrado na entrada;
saída: a
saída x corresponde ao subscrito da matriz;
se não houver x, ela produz NULL;
caso_de_entrada:
5
1 3 4 6 8
6
output_case :
3
código:
#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;
}
Complexidade de tempo : O (logn);
Quarta questão, multiplicação de números inteiros grandes (análise)
Descrição do problema: Como
dois inteiros positivos muito grandes (dados na forma binária) podem reduzir a complexidade do tempo?
análise:
Complexidade de tempo : de O (n ^ 2) ------> O (n ^ 1,59)
Pergunta cinco, multiplicação da matriz de Strassen (análise)
Descrição do problema:
multiplique a matriz quadrada nXn A pela política nXn B para formar a política nXn C; como reduzir
a complexidade de tempo de O (n ^ 3)
?
Análise:
Divida a matriz nXn em 4 (n / 2) matrizes X (n / 2), então a complexidade do tempo é:
Complexidade do tempo : O (n ^ 3) --------> O (n ^ 2,81 )