Ejemplo de algoritmo codicioso

        

Tabla de contenido

algoritmo codicioso

cambio de problema

cantidad máxima

pila de fruta


algoritmo codicioso

        Algoritmo codicioso (algoritmo codicioso, también conocido como el algoritmo codicioso) significa que al resolver el problema, siempre haga la mejor elección en el presente. Es decir, sin considerar la optimalidad global, el algoritmo obtiene una solución óptima local en cierto sentido. El algoritmo codicioso no puede obtener la solución óptima general para todos los problemas, la clave es la elección de la estrategia codiciosa.

cambio de problema

Moneda: 1 2 4 5 10 varias hojas, cambio: n yuan. esquema de cambio de salida

Ideas:

(1) Debido a que la codicia es encontrar la solución óptima, debemos comenzar a buscar el valor de moneda más grande

(2) Cada vez que se encuentre un valor de moneda que cumpla con las condiciones, reste n el dinero que se ha encontrado y luego continúe el bucle hasta que n no sea mayor que 0 y deténgase.

import java.util.Scanner;

public class Greed {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        greedy(n);
    }

    public static void greedy(int n) {
        int[] money = {
    
    10, 5, 4, 2, 1};//钱的面值,从大到小,因为要找最优解。
        int i = 0;//表示目前用money数组中哪一个面值的钱去找零,最开始从10快开始。
        int[] num = new int[money.length];
        while (n > 0) {
    
    //n>0说明钱还没有找完,所以继续循环
            if (n >= money[i]) {
    
    //剩余要找的钱必须大于等于当前money[i]这个面值
                int zs = n / money[i];
                n -= zs * money[i];
                num[i]+= zs;//当前这个面值的数量加上zs
            } else{
    
    //如果当前面值不能找开就i++
                i++;
            }
        }
        for (int j = 0; j < num.length; j++) {
    
    //输出
            if (num[j] > 0) {
    
    //说明当前这个面值的钱使用到了,所以才能输出
                System.out.printf("面值:%d 张数:%d ", money[j], num[j]);
            }
        }
    }
}

           


cantidad máxima

        Si el número entero n representa la cantidad total de dinero que ya está en el pozo de premios actual, elimine m números de n, y la cantidad correspondiente al valor restante es el dinero que se puede quitar. Sabemos que la naturaleza humana es codiciosa, así que ayude a Xiaoming a hacer que el nuevo número formado por los números restantes en el orden original sea el más grande.

Por ejemplo, cuando n = 92081346718538, m = 10, el nuevo número máximo es 9888

Ejemplo de entrada:

92081346718538 10

1008908 5

Salida de muestra:

9888

98

Ideas:

(1) Primero convierta el problema de eliminación en un problema de retención y use la idea codiciosa para encontrar el valor máximo fuera del número no reservado cada vez

(2) Supongamos que la entrada es 92081346718538 10, por lo que necesitamos eliminar 10 de los 14 números, para que podamos elegir un valor máximo entre los primeros 11 números, y luego el siguiente ciclo buscará desde este valor máximo hasta el número 12. número más grande, hasta que la i del bucle for sea igual al número reservado, deténgase.

import java.util.Scanner;

public class selectMaxNumber {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            String n = scanner.next();//输入n为String类型
            int m = scanner.nextInt();//输入需要删除数的个数
            if (n.length() <= m) {
                System.out.println("输入错误,请重新输入");
            }
            char[] a = n.toCharArray();//将String类型的数转为char数组,为了循环判断使用
            String max = "";//定义max变量存放最后早到的最大数
            int retain = a.length - m;//将删除问题变成保留问题
            int lastselect = -1;//存放最大数在数组中的位置,开始的时候定义为-1,在循环时在+1就从0开始了
            for (int i = 1; i <= retain; i++) {
                char big = '0';//循环比较前先假设big为最小的值
                    for (int j = lastselect + 1; j < a.length - (retain - i); j++) {
                    //这里lastselect+1主要是因为在找到一个最大的数后下次循环就从这个最大数的下一个开始
                    /*
                    j < a.length - (retain - i)这个区间判断方法是
                    第一次循环判断的范围是j < 11,也就是0到10,因为总共有14个数,需要保留四个,
                    所以第一次就需要在前11个中选择一个最大的数,然后每次循环结束范围都要往后移一位
                    例如:92081346718538删掉十个数,第一次循环判断在92081346718中
                    第二次循环判断在20813467185中,第三次在134671853中,第四次就在538中
                     */

                    if (a[j] > big) {
                        big = a[j];
                        lastselect = j;//找到大的数就将j赋给存放最大数地址的这个变量
                    }
                }
                max += big;//每次找出那个最大的数后就拼接到max中
            }
            System.out.println(max);
        }
    }
}

 


pila de fruta

        En un huerto, Duoduo ya ha derribado todas las frutas y las ha dividido en diferentes montones según los diferentes tipos de frutas. Duoduo decidió combinar todas las frutas en montones. Cada vez que se fusiona, Duoduo puede fusionar dos montones de frutas. La fuerza física consumida es igual a la suma de los pesos de los dos montones de frutas. Se puede ver que después de que todas las frutas se han fusionado n-1 veces, solo queda una pila. La energía total consumida por Duoduo al fusionar las frutas es igual a la suma de la energía consumida por cada fusión.

        Debido a que lleva mucho esfuerzo mover estas frutas a casa, Duoduo debe ahorrar energía tanto como sea posible al fusionar las frutas. Suponiendo que cada fruta pesa 1, y se conoce la cantidad de tipos de frutas y la cantidad de cada fruta, usted La tarea es diseñar un plan de secuencia combinada para minimizar la energía consumida por Duoduo y generar el valor de la energía mínima.

Entrada: La primera línea: un número entero n (1<=n<=100), que indica el número de tipos de fruta. La segunda línea: contiene n enteros, separados por espacios. Salir automáticamente cuando n es igual a 0

Ideas:

(1) Detener si n==0 y enviar el peso directamente si n==1

(2) Si n>1, bucle, primero ordene la matriz de menor a mayor, y luego agregue el primer número y el segundo número de la matriz en cada ciclo, y asigne la posición vacante al infinito, para que pueda agregar la fase del bucle .

import java.util.Arrays;
import java.util.Scanner;

public class pileFruit {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            int n = scanner.nextInt();//输入果子总共的堆数
            int[] m = new int[n];//表示n堆果子重量的数组
            if (n == 0) break;//n==0时直接结束
            if (n == 1) {
                //如果只有一堆果子,就直接输出这堆果子的重量
                System.out.println(scanner.nextInt());
                continue;
            }
            for (int i = 0; i < n; i++) {
                m[i] = scanner.nextInt();//输入每堆果子的重量
            }
            int sum = 0;//记录总共搬运的重量
            for (int i = 0; i < n - 1; i++) {//循环n-1次,例如三堆果子只需要搬2次
                Arrays.sort(m);//将m数组排序
                sum = sum + m[0] + m[1];//先从最轻的开始合并
                m[0] += m[1];//搬完后m[0]就表示合并后的重量
                m[1] = Integer.MAX_VALUE;//然后m[1]给无穷大,这样每次循环就会到数组最后
                System.out.println(Arrays.toString(m));//查看数组数的排序
            }
            System.out.println(sum);
        }
    }
}

 Se puede ver que se emite la matriz antes de cada clasificación, y también se emite la energía total consumida al final.

 

Supongo que te gusta

Origin blog.csdn.net/weixin_71646897/article/details/129768164
Recomendado
Clasificación