Projeto de algoritmo e análise do problema de meio conjunto (C ++)

Descrição do Problema

É necessário encontrar o número de números com as seguintes propriedades (incluindo o número natural de entrada n):
primeiro insira um número natural n (n <= 500) e, em seguida, processe este número natural da seguinte maneira:

  • Fazer nada
  • Adicione um número natural à sua esquerda, mas o número natural não pode exceder a metade do número original
  • Depois de adicionar o número, continue a processar de acordo com esta regra até que nenhum número natural possa ser adicionado

Se você inserir 6, haverá
6
16
26
126
36
136
saída 6

analise de problemas

Podemos facilmente encontrar a fórmula de recorrência para o número de conjuntos de meio-número:
f (n) = 1 + ∑ i = 1 n / 2 f (i) f (n) = 1 + \ sum_ {i = 1} ^ {n / 2 } f (i)f ( n )=1+i = 1n / 2f ( i )
Usamos recursão para realizar cálculos recursivos.Para evitar cálculos repetidos, usamos busca de memória.

Implementação de algoritmo

#include <iostream>
#include <cstring>

#define N 500
using namespace std;

int a[N] = {
    
    0};   //存储计算过的数据 初始化所有值为零
//求半数集算法
int halfSet(int);

int main()
{
    
    
    int n;
    cout<<"请输入n:";
    cin>>n;
    cout<<n<<"的半数集元素数量为:"<<halfSet(n)<<endl;
    return 0;
}

int halfSet(int n){
    
    
    if(a[n] > 0) return a[n];
    int ret = 1;
    for(int i=1;i<=n/2;i++){
    
    
        ret = ret + halfSet(i);
    }
    a[n] = ret;
    return ret;
}

No entanto, há falhas no algoritmo acima e haverá subproblemas repetitivos. Por exemplo, há dois 1224s na metade de 24. Os métodos de geração são diferentes, mas os resultados são os mesmos. Precisamos melhorar o algoritmo novamente.

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <set>

using namespace std;

//求半数集算法 改进 无重复子问题
void halfSet(int,set<string>&,string);

int main()
{
    
    
    int n;
    set<string> s;
    char *str = new char[3];

    cout<<"请输入n:";
    cin>>n;

    if(n > 500){
    
    
        cout<<"数据超范围!";
        exit(0);
    }

    halfSet(n,s,string(itoa(n,str,10)));

    cout<<n<<"的半数集元素数量为:"<<s.size()+1<<endl;
    return 0;
}

void halfSet(int n,set<string> &s,string str){
    
    
    char *strs = new char[3];
    string mStr;

    for(int i=1;i<=n/2;i++){
    
    
        mStr = string(itoa(i,strs,10)) + str;
        s.insert(mStr);
        halfSet(i,s,mStr);
    }
}

Recomendado por outros artigos neste blog

Registro sobre a inicialização automática da matriz de inteiros C ++ para zero

Seleção de tempo linear para projeto e análise de algoritmo

Divida e conquiste exercícios de estratégia para design e análise de algoritmo (parte 2)

Divida e conquiste exercícios de estratégia para design e análise de algoritmos (on)

Divida e conquiste estratégia para design e análise de algoritmos

Projeto de algoritmo e análise de exercícios de algoritmo recursivo (parte 2)

Projeto de algoritmo e análise de exercícios de algoritmo recursivo (on)

Acho que você gosta

Origin blog.csdn.net/L333333333/article/details/102671667
Recomendado
Clasificación