Greedy algorithm example

        

Table of contents

Greedy Algorithm

change problem

maximum amount

pile of fruit


Greedy Algorithm

        Greedy algorithm (greedy algorithm, also known as the greedy algorithm) means that when solving the problem, always make the best choice at present. That is to say, without considering the overall optimality, the algorithm obtains a local optimal solution in a certain sense. The greedy algorithm cannot obtain the overall optimal solution for all problems, the key is the choice of greedy strategy.

change problem

Currency: 1 2 4 5 10 several sheets, change: n yuan. output change scheme

Ideas:

(1) Because greed is to find the optimal solution, we need to start looking for the largest currency value

(2) Every time a currency value that meets the conditions is found, let n subtract the money that has been found, and then continue to loop until n is not greater than 0 and stop

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]);
            }
        }
    }
}

           


maximum amount

        If the integer n represents the total amount of money already in the current prize pool, please delete m numbers from n, and the amount corresponding to the remaining value is the money that can be taken away. We know that human nature is greedy, so please help Xiaoming to make The new number formed by the remaining numbers in the original order is the largest.

For example, when n = 92081346718538, m = 10, the new maximum number is 9888

Sample input:

92081346718538 10

1008908 5

Sample output:

9888

98

Ideas:

(1) First turn the deletion problem into a retention problem, and use the greedy idea to find the maximum value outside the non-reserved number each time

(2) Suppose the input is 92081346718538 10, so we need to delete 10 of the 14 numbers, so we can choose a maximum value among the first 11 numbers, and then the next cycle will search from this maximum value to the 12th number The largest number, until the i of the for loop is equal to the reserved number, stop.

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);
        }
    }
}

 


pile of fruit

        In an orchard, Duoduo has already knocked down all the fruits, and divided them into different piles according to different types of fruits. Duoduo decided to combine all the fruits into piles. Every time he merges, Duoduo can merge two piles of fruits together. The physical strength consumed is equal to the sum of the weights of the two piles of fruits. It can be seen that after all the fruits have been merged n-1 times, there is only one pile left, and the total energy consumed by Duoduo when merging the fruits is equal to the sum of the energy consumed by each merger.

        Because it takes a lot of effort to move these fruits home, Duoduo should save energy as much as possible when merging the fruits. Assuming that each fruit weighs 1, and the number of types of fruits and the number of each fruit are known, you The task is to design a combined sequence plan to minimize the energy consumed by Duoduo, and output the value of the minimum energy.

Input: The first line: an integer n (1<=n<=100), indicating the number of types of fruit. The second line: contains n integers, separated by spaces. Automatically exit when n is equal to 0

Ideas:

(1) Stop if n==0, and output weight directly if n==1

(2) If n>1, loop, first sort the array from small to large, and then add the first number and the second number of the array each time through the loop, and give the space to infinity, so that you can loop phase add.

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);
        }
    }
}

 It can be seen that the array before each sorting is output, and the total energy consumed at the end is also output.

 

Guess you like

Origin blog.csdn.net/weixin_71646897/article/details/129768164