贪心算法的思考

目录

概念

基本思路

例题:钱币找零

课程安排 


 

概念

什么是贪心算法?就是对问题求解的时候,能够做出当前(关键是当前)看起来最好的选择,也就是它强调的是局部最优解

所以说,对于整个问题来说不一定能够就是求得最优解,需要看问题

什么时候选择贪心算法:问题必须具备无后效性,也就是某个状态在以后的过程中不会影响之前的状态,只与当前状态有关

关键:贪心算法只需考虑一个选择(亦即,贪心的选择);在做贪心选择时,子问题之一必须是空的,因此只留下一个非空子问题

心算法通常是自顶向下地做出贪心选择,不断地将给定的问题实例归约为更小的问题。贪心算法划分子问题的结果,通常是仅存在一个非空的子问题

基本思路

1.把问题分为多个子问题——>2.然后对每个问题都求解得到子问题的局部最优解——>3.把子问题最优解进行合并判断得到最后问题解

例题:钱币找零

假设纸币金额为1元、5元、10元、20元、50元、100元,要求我们找零兑的钱纸最少,123元应该尽可能兑换少的纸币。
按尝试应该兑换1张100、1张20元和3张1元的。

思想:每一步尽可能用面值大的纸币——>1.遍历每一种面额情况100,50...——>2.然后循环每种面额的能够换几次

 /**
     * 零钱兑换
     * @param money
     */
    static void splitChange(int money) {
        int[]prices={100,50,20,10,5,1};
        int[]notes=new int[prices.length];//记录每种面额使用张数
        int change=money;

        if(money>0){
            while(change>0){
                //面额的选择
                for (int i = 0; i < prices.length; i++) {
                    //记录面额的使用数
                   int count=0;
                   //看这种面额的能循环找出几张
                    for (int k = 0; change- prices[i]>=0 ; k++) {
                        if(change-prices[i]>=0){
                            change=change-prices[i];
                            count++;
                        }else{
                            break;
                        }
                    }
                    notes[i]=count;
                }
            }
        }
        System.out.println("找零:");
        for (int num = 0; num < prices.length; num++) {
            System.out.print(notes[num] + "张" + prices[num] + "元  ");
        }
    }

课程安排 

思路:1.按照时间对课程进行排序——>2.然后遍历课程进行筛选,如果时间比截至日期短则进行添加——>3.如果遍历课程发现超过时间了,则对之前已经筛选过的课程进行遍历然后将耗时较长的进行替换,然后更新时间 

  /**
     * 课程安排
     * 思路:1.给定一个数组courses ,对其进行排序并维护当前日期——>2.可以选择课程,那么增加当前日期
     * ——>3.如果不可选,选择已经选过耗时最长的课程比较当前课程哪个时间长,长的不要——>保证了指定时间范围内能够选择的最多课程
     * 它的每一个元素courses表示两门课程之间的先修顺序。
     * 例如courses[i] = [ai, bi]表示想要学习课程 ai,需要先完成课程 bi
     *
     * @param courses:课程对应时长,以及截止日期
     * @return
     */
    public int scheduleCourse(int[][] courses) {
        //1.排序
        Arrays.sort(courses, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                return o1[1] - o2[1];
            }
        });

        int count = 0, curtime = 0;
        for (int i = 0; i < courses.length; i++) {
            /**
             * 2.遍历每个课程的时间,若可选(<截止日期),增加当前时间,并且将当前课程放入courses
             */
            if (curtime + courses[i][0] <= courses[i][1]) {
                courses[count++] = courses[i];
                curtime += courses[i][0];
            } else {
                int max_i = i;
                /**
                 * 3.遍历已经选的课程count,将耗时较长的替换
                 */
                for (int j = count - 1; j >= 0; j--) {
                    //3.1找到已选课程中耗时较长的课程
                    if (courses[j][0] > courses[i][0]) max_i = j;
                }
                //3.2更新课程,并且更新最大时间
                if (courses[max_i][0] > courses[i][0]) {
                    curtime += courses[i][0] - courses[max_i][0];
                    courses[max_i] = courses[i];
                }
            }

        }
        return count;
    }
public class greedyProgramTest {
    public static void main(String[] args) {
        //找零问题
        int money = 123;
        greedyProgram.splitChange(money);

        System.out.println();
        System.out.println("-------");

        //多机调度问题
        int[] a = {5,4,2,14,16,6,5,3};
        int m = 3;
        System.out.println("总时间为:"+greedyProgram.greedy(a,m));

        System.out.println("-------");

        //课程表
        int[][] course = {{2,5},{2,19},{1,8},{1,3}};
        System.out.println(Solution.scheduleCourse(course));
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Fairy要carry

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

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

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

打赏作者

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

抵扣说明:

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

余额充值