【备战蓝桥】JavaB组算法小讲解——贪心算法

        大家好,这里是祁十一!Now,我想给大家讲一下贪心算法。贪心法,顾名思义,就是贪多、贪好。那么,让我们来一起看一下贪心算法是怎么“贪婪无言”的吧! 

目录

1、什么是贪心算法?

2、怎么理解贪心算法?

【蓝桥算法训练】最大最小公倍数

3、算法就要多加练习!

【蓝桥算法训练】排队接水2


1、什么是贪心算法?

        贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解 。贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择 。

2、怎么理解贪心算法?

        先举个简单的例子!

【蓝桥算法训练】最大最小公倍数

【题目】已知一个正整数N,问从1~N中任选出三个数,他们的最小公倍数最大可以为多少。输入一个正整数N。输入一个正整数N。输出一个整数,表示你找到的最小公倍数。

说实话,再没学贪心之前,我是这样写的(满怀信心的我在看到运行超时的一瞬间直呼救命!)

import java.util.*;
public class Main{
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		Random r = new Random();
		int a=r.nextInt(n);
		int b=r.nextInt(n);
		int c=r.nextInt(n);
		LCM(a,b,c);
	}
	public static void LCM(int a,int b,int c){
        int k=getMax(a,b,c);
        for (int i=k;;i++){
        	if(i%a==0 && i%b==0 && i%c==0){
        		System.out.println(i);
        		break;
			}
        }
	}
	public static  int  getMax(int a ,int b,int c){
		int []arr={a,b,c};
		Arrays.sort(arr) ;
		return arr[2];
	}
}

        在重新读了三遍题目以后,我发现了有一个突破点!要求最大的最小公倍数,当三个数互为质数的时候且乘起来最大不就可以啦!所以,我们用贪心的思维(咱搞就要搞最大!),直接考虑取后三个数(n、n-1、n-2)。注意n的范围,代码中已标出原因。

import java.util.*;
public class Main{
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		long n=sc.nextLong();
        //n如果小于2,直接就不用求了
		if(n<=2){
			System.out.println(n);
		}
		if(n>2){
			if(n%2!=0)//当n为奇数的时候,n-2也是奇数,三数相乘输出这个数为最大公倍数
				System.out.println(n*(n-1)*(n-2));
            //当n为偶数,n和n-2有约数2,再向前推一个,n与n-3相差3,判断一下能不能被3整除
			if(n%3==0&&n%2==0) //若能整除,直接整体向前移动,变成“奇偶奇”形式
				System.out.println((n-1)*(n-2)*(n-3));
			if(n%3!=0&&n%2==0)//若不能整除,输出即可
				System.out.println(n*(n-1)*(n-3));
		}		
	}
}

3、算法就要多加练习!

【蓝桥算法训练】排队接水2

【题目】有N个人排队到M个水龙头去打水,他们装满水桶的时间T1,T2……Tn为整数且各不相等,应如何安排他们的打水顺序才能使他们花费的总时间最少?

(输入)第1行:两个整数n和m,n表示人的个数,m表示水龙头的个数;第2行,n个数分别表示n个人装水的时间。(输出)一个整数,表示总花费的最少时间。

        这个题猛得一看很奇怪,因为打水再怎么打要都是一个人接完另一个上,时间好像都是一样的啊,仔细一看样例(如下)。

输入输出
6 2
5 4 6 2 1 7
40

        好像明白了什么又好像什么也没明白,那笔一写一画,我知道了,他的过程可能是这样的:

        n=6,且排完序为1、2、4、5、6、7;m=2,水龙头A和水龙头B。

水龙头A水龙头B
1(1)2(2)
4(1+4)5(2+5)
6(1+4+6)7(2+5+7)
A总1+5+11=17B总2+7+14=23
总和为40

        思路有了,那么代码如下:

import java.util.*;
public class Main{
	public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n=sc.nextInt();
        int m=sc.nextInt();
        int[] watertime=new int[n];
        int[] num=new int[m];
        int sum=0;
        //输入每个人接水的时间
        for(int i=0;i<n;i++) {
        	watertime[i]=sc.nextInt();
        }
        sc.close();
        //排序(递增)
        Arrays.sort(watertime);
        //因为先排小的时间会短,要使总和最小,m条路都要时间短一点
        for(int i=0;i<n;) {    
        	for(int j=0;j<m&&i<n;i++,j++) {    
          		num[j]=watertime[i]+num[j];
            	sum=num[j]+sum;
            }
        }
        System.out.println(sum);    
	}
}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

祁十一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值