[Notas do algoritmo] Algoritmo ganancioso

Prefácio: O aprendizado do algoritmo guloso é principalmente para aumentar experiência e experiência, ou seja, fazer mais para acumular experiência, a seguir apresentará a diversão do algoritmo guloso através de vários tópicos!

Diretório de artigos

1. Introdução básica ao algoritmo guloso

  • É um padrão local mais utilitário, sempre fazendo a melhor escolha na visão atual
  • A dificuldade está em provar que o critério local mais utilitário pode levar à solução ótima global
  • Ganancioso em geralordenareamontoarrelacionado
  • A dificuldade do algoritmo guloso é como provar que o padrão é viável, mas a prova muitas vezes é difícil, e o logaritmo pode ser usado para verificar se o método final é viável

2. Tópicos

Questão 1: Dado um array strs composto de strings, todas as strings devem ser concatenadas, e o resultado com a menor ordem lexicográfica entre todos os resultados de concatenação possíveis é retornado.

Modelo de método: Para obter o resultado com a menor ordem lexicográfica, podemos ordenar o array de forma que a ordem lexicográfica da string concatenada pelo array ordenado seja a menor. A ordenação é para string a e string a + bb b + adepois de concatenar e comparar o tamanho lexicográfico dos dois. Se for a + bmenor , então a string a é classificada antes da string b.

public static class MyComparator implements Comparator<String> {
    
    
    @Override
    public int compare(String o1, String o2) {
    
    
        return (o1 + o2).compareTo(o2 + o1);
    }
}

public static String lowestString(String[] strs) {
    
    
    if (strs == null || strs.length == 0) {
    
    
        return "";
    }
    Arrays.sort(strs, new MyComparator());
    String ans = "";
    for (int i = 0; i < strs.length; i++) {
    
    
        ans += strs[i];
    }
    return ans;
}

Código de amostra:

public static void main(String[] args) {
    
    
    String[] strs = {
    
    "ba", "b", "cda"};
    System.out.println(lowestString(strs));
}
// 结果为:babcda

Pergunta 2: Alguns projetos precisam ocupar uma sala de conferência para apresentações, e a sala de conferência não pode acomodar as apresentações de dois projetos ao mesmo tempo. Dê-lhe a hora de início e fim de cada projeto, e você pode organizar o cronograma de apresentação.A sala de conferência é necessária para ter mais apresentações. Retorna a maioria das apresentações

hora de término mais cedo

Modelo de método: Quando pensamos sobre esse problema, podemos pensar em usar o tempo de início mais cedo ou o tempo de pregação mais curto para verificação, mas esse tipo de pensamento ganancioso está errado, a maneira correta é pensar no problema com o tempo de término mais cedo . Encontre a primeira reunião com o horário de término mais cedo, exclua as reuniões restantes com um horário de início anterior ao horário de término mais cedo e encontre a segunda reunião com o horário de término mais cedo...

public static class Program {
    
    
    public int begin;
    public int end;

    public Program(int begin, int end) {
    
    
        this.begin = begin;
        this.end = end;
    }
}
public static int bestArrange(Program[] programs) {
    
    
    Arrays.sort(programs, new MyComparator());
    int timeLine = 0;
    int count = 0;
    for (int i = 0; i < programs.length; i++) {
    
    
        if (programs[i].begin >= timeLine) {
    
    
            count++;
            timeLine = programs[i].end;
        }
    }
    return count;
}
public static class MyComparator implements Comparator<Program> {
    
    
    @Override
    public int compare(Program o1, Program o2) {
    
    
        return o1.end - o2.end;
    }
}

Código de amostra:

public static void main(String[] args) {
    
    
    Program[] programs = {
    
     new Program(1, 2), new Program(1, 5), new Program(3, 4), new Program(5, 6) };
    System.out.println(bestArrange(programs));
}
// 结果为:3

Pergunta 3: Uma barra de ouro cortada ao meio custa a mesma quantidade de chapa de cobre que o comprimento. Por exemplo, uma barra de ouro com um comprimento de 20 custará 20 placas de cobre, não importa como seja cortada. Um grupo de pessoas quer dividir toda a barra de ouro, como dividir a placa mais de cobre? Insira uma matriz, retorne o custo mínimo de divisão

Exemplo:

Por exemplo, dada uma matriz {10, 20, 30}, que representa um total de três pessoas, o comprimento de toda a barra de ouro é 60 e a barra de ouro precisa ser dividida em três partes: 10, 20 e 30 .

Se você primeiro dividir as barras de ouro de comprimento 60 em 10 e 50, custará 60; em seguida, divida as barras de ouro de comprimento 50 em 20 e 30, custando 50 e custando 110 placas de cobre no total

Se você primeiro dividir a barra de ouro de comprimento 60 em 30 e 30, custa 60, e depois dividir a barra de ouro de comprimento 30 em 30 e 10, que custa 30 e custa 90 placas de cobre no total

Modelo do método: Ao pensar nesta questão, você pode pensar em cortar com o comprimento da maior parte da barra de ouro, mas a ideia gananciosa está errada (se você quiser dividir em partes com comprimentos de 97, 98, 99, e 100, você deve primeiro dividir a barra de ouro em 97+98 e 99+100 partes). Aqui você pode construir um pequeno heap de raiz e, em seguida, abrir o topo do heap e adicionar os dois elementos. O resultado da adição é o custo de dividir as duas barras de ouro e, em seguida, o resultado é adicionado ao heap e as etapas acima são continuadas até que haja apenas um no heap. Valor numérico

public static int lessMoney(int[] arr) {
    
    
    Queue<Integer> queue = new PriorityQueue<>();
    for(int num : arr) {
    
    
        queue.add(num);
    }
    int money = 0;
    int cur = 0;
    while(queue.size() > 1) {
    
    
        cur = queue.poll() + queue.poll();
        money += cur;
        queue.add(cur);
    }
    return money;
}

Código de amostra:

public static void main(String[] args) {
    
    
    int[] arr = {
    
    10, 20, 30};
    System.out.println(lessMoney(arr));
}
// 结果为:90

Pergunta 4: Entrada: custos de matriz de números positivos, lucros de matriz de números positivos, número positivo K, número positivo M. cost[i] representa o custo do item i, profit[i] representa o dinheiro que o item que eu posso ganhar após deduzir o custo, K representa que você só pode fazer K itens em série no máximo e M representa seus fundos iniciais. Explicação: Se você não terminou um projeto, a renda obtida imediatamente pode ajudá-lo a fazer o próximo projeto. Os projetos não podem ser feitos em paralelo. Saída: A quantidade máxima de dinheiro que você recebeu por último

Modelo de método: você pode construir um heap de raiz pequeno com custo de projeto de baixo a alto, colocar todos os itens no heap e, em seguida, construir um heap de raiz grande com lucro de projeto de alto a baixo e consumir menos no heap de raiz pequeno do que o Os projetos com os fundos são exibidos e adicionados à pilha de raiz grande, e o projeto com o maior lucro é selecionado para compra e, em seguida, as etapas acima são executadas por sua vez.

public static class Program {
    
    
    public int cost;
    public int profit;

    public Program(int cost, int profit) {
    
    
        this.cost = cost;
        this.profit = profit;
    }
}

public static class MinCostComparator implements Comparator<Program>{
    
    

    @Override
    public int compare(Program o1, Program o2) {
    
    
        return o1.cost - o2.cost;
    }

}

public static class MaxProfitComparator implements Comparator<Program>{
    
    

    @Override
    public int compare(Program o1, Program o2) {
    
    
        return o2.profit - o1.profit;
    }

}

public static int findMaximizedCapital(int K, int W, int[] profits, int[] capital) {
    
    
    Queue<Program> minCostQ = new PriorityQueue<>(new MinCostComparator());
    Queue<Program> maxProfitQ = new PriorityQueue<>(new MaxProfitComparator());
    for(int i = 0; i < capital.length; i++) {
    
    
        Program program = new Program(capital[i], profits[i]);
        minCostQ.add(program);
    }
    while(K > 0) {
    
    
        while(minCostQ.size() > 0 && minCostQ.peek().cost <= W) {
    
    
            maxProfitQ.add(minCostQ.poll());
        }
        if(maxProfitQ.isEmpty()) {
    
    
            break;
        }
        W += maxProfitQ.poll().profit;
        K--;
    }
    return W;
}

Código de amostra:

public static void main(String[] args) {
    
    
    int[] capital = {
    
    2,1,6,4};
    int[] profits = {
    
    2,3,1,4};
    int K = 3;
    int W = 1;
    System.out.println(findMaximizedCapital(K,W,profits,capital));
}
// 结果为:10

Pergunta 5: Dada uma string str, ela consiste apenas em caracteres 'X' e '.'. 'X' significa uma parede, nenhuma luz pode ser colocada e não precisa ser acesa, '.' significa uma área residencial, onde as luzes podem ser colocadas e precisam ser acesas. Se a lâmpada for colocada na posição i, as três posições i-1, i e i+1 podem ser acesas. Retorna pelo menos quantas luzes são necessárias se todas as posições em str que precisam ser acesas estiverem acesas

Modelo de método: assumindo que a posição do índice é uma parede, então índice = índice + 1; quando a posição do índice é um assentamento e a posição do índice + 1 é uma parede, é necessária uma lâmpada e índice = índice + 2; quando a posição do índice é local residencial, a posição do índice+1 é um local residencial, não importa se a posição do índice+2 é um local residencial ou uma parede, é necessária uma lâmpada e índice = índice+3

public static int minLight(String road) {
    
    
    char[] str = road.toCharArray();
    int index = 0;
    int light = 0;
    while(index<str.length) {
    
    
        if(str[index] == 'X') {
    
    
            index++;
        }else {
    
    
            light++;
            if(index+1==str.length) {
    
    
                break;
            }else {
    
    
                if(str[index+1]=='X') {
    
    
                    index=index+2;
                }else {
    
    
                    index=index+3;
                }
            }
        }
    }
    return light;
}

Código de amostra:

public static void main(String[] args) {
    
    
    String road = "X.XX..X...X....X";
    System.out.println(minLight(road));
}
// 结果为:5

Acho que você gosta

Origin blog.csdn.net/weixin_51367845/article/details/123167925
Recomendado
Clasificación