[Notas del algoritmo] Algoritmo codicioso

Prefacio: el aprendizaje del algoritmo codicioso es principalmente para aumentar la experiencia y la experiencia, es decir, para hacer más para acumular experiencia, ¡a continuación se presentará la diversión del algoritmo codicioso a través de varios temas!

Directorio de artículos

1. Introducción básica al algoritmo codicioso

  • Es un estándar local más utilitario, siempre haciendo la mejor elección en la vista actual.
  • La dificultad radica en probar que el criterio local más utilitario puede conducir a la solución óptima global.
  • codiciosos en generalclasificarymontónrelacionada
  • La dificultad del algoritmo codicioso es cómo probar que el estándar es factible, pero la prueba suele ser difícil y el logaritmo se puede usar para verificar si el método final es factible.

2. Temas

Pregunta 1: dada una matriz strs compuesta por cadenas, todas las cadenas deben concatenarse y se devuelve el resultado con el orden lexicográfico más pequeño entre todos los resultados de concatenación posibles.

Plantilla de método: para obtener el resultado con el orden lexicográfico más pequeño, podemos ordenar la matriz de modo que el orden lexicográfico de la cadena concatenada por la matriz ordenada sea el más pequeño. La intercalación es para la cadena A y la cadena a + bB b + adespués de concatenar y comparar el tamaño lexicográfico de las dos. Si es a + bmenor , entonces la cadena A se ordena antes que la cadena 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 muestra:

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

Pregunta 2: Algunos proyectos necesitan ocupar una sala de conferencias para presentaciones, y la sala de conferencias no puede acomodar las presentaciones de dos proyectos al mismo tiempo. Le proporciona la hora de inicio y la hora de finalización de cada proyecto, y puede organizar el horario de presentación. Se requiere que la sala de conferencias tenga la mayor cantidad de presentaciones. Devuelve la mayoría de las presentaciones

tiempo de finalización más temprano

Plantilla de método: cuando pensamos en este problema, podemos pensar en usar el tiempo de inicio más temprano o el tiempo de prédica más corto para la verificación, pero este tipo de pensamiento codicioso está mal, la forma correcta es pensar en el problema con el tiempo de finalización más temprano. . Busque la primera reunión con la hora de finalización más temprana, luego elimine las reuniones restantes con una hora de inicio anterior a la hora de finalización más temprana, luego busque la segunda reunión con la hora de finalización más temprana...

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 muestra:

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

Pregunta 3: Una barra de oro cortada por la mitad cuesta la misma cantidad de placa de cobre que la longitud. Por ejemplo, una barra de oro con una longitud de 20 costará 20 placas de cobre sin importar cómo se corte. Un grupo de personas quiere dividir toda la barra de oro, ¿cómo dividir la mayor cantidad de placa de cobre? Ingrese una matriz, devuelva el costo mínimo de dividir

Ejemplo:

Por ejemplo, dada una matriz {10, 20, 30}, que representa un total de tres personas, la longitud de la barra de oro completa es 60, y la barra de oro debe dividirse en tres partes: 10, 20 y 30 .

Si primero divides los lingotes de oro de 60 de longitud en 10 y 50, costará 60; luego divides los lingotes de oro de 50 de longitud en 20 y 30, cuestan 50 y cuestan 110 placas de cobre en total

Si primero divide el lingote de oro de 60 de longitud en 30 y 30, cuesta 60, y luego divide el lingote de oro de 30 de longitud en 30 y 10, que cuesta 30, y cuesta 90 placas de cobre en total.

Plantilla de método: al pensar en esta pregunta, puede pensar en cortar con la longitud de la parte más grande de la barra de oro, pero la idea codiciosa es incorrecta (si desea dividirla en partes con longitudes de 97, 98, 99, y 100, primero debes dividir el lingote de oro en 97+98 y 99+100 partes). Aquí puede crear un pequeño montón raíz y luego abrir la parte superior del montón y agregar los dos elementos. El resultado de la suma es el costo de dividir los dos lingotes de oro, y luego el resultado se agrega al montón, y los pasos anteriores se continúan hasta que solo queda uno en el montón.

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 muestra:

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

Pregunta 4: Entrada: costos de matriz de números positivos, ganancias de matriz de números positivos, número positivo K, número positivo M. cost[i] representa el costo del artículo i, profits[i] representa el dinero que puedo ganar después de deducir el costo, K representa que solo puedes hacer K artículos en serie como máximo y M representa tus fondos iniciales. Explicación: si no ha terminado un proyecto, los ingresos que obtiene de inmediato pueden ayudarlo a realizar el próximo proyecto. Los proyectos no se pueden hacer en paralelo. Salida: la cantidad máxima de dinero que obtuviste por última vez

Plantilla de método: puede crear un montón raíz pequeño con el costo del proyecto de menor a mayor, colocar todos los elementos en el montón y luego crear un montón raíz grande con las ganancias del proyecto de mayor a menor y consumir menos en el montón raíz pequeño que en el montón raíz pequeño. actual Los proyectos con los fondos se abren y se agregan a la gran pila de raíces, y el proyecto con la mayor ganancia se selecciona para la compra, y luego los pasos anteriores se llevan a cabo a su 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 muestra:

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

Pregunta 5: Dada una cadena str, solo consta de los caracteres 'X' y '.'. 'X' significa una pared, no se pueden colocar luces y no es necesario encenderlas; '.' significa un área residencial, donde se pueden colocar luces y es necesario encenderlas. Si la lámpara se coloca en la posición i, se pueden encender las tres posiciones i-1, i e i+1. Devuelve al menos cuántas luces se requieren si todas las posiciones en str que deben encenderse están encendidas

Plantilla de método: suponiendo que la posición de índice es una pared, entonces índice = índice+1; cuando la posición de índice es un asentamiento y la posición de índice+1 es una pared, se requiere una lámpara e índice = índice+2; cuando la posición del índice es un sitio residencial, la posición del índice+1 es un sitio residencial, no importa si la posición del índice+2 es un sitio residencial o una pared, se requiere una lámpara 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 muestra:

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

Supongo que te gusta

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