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
- 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.
- 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
- 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
- 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
- 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
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 + b
b b + a
depois de concatenar e comparar o tamanho lexicográfico dos dois. Se for a + b
menor , 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