Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 555|回复: 0

[算法学习]学习常用算法之(2)贪婪法

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-27 00:05:21 | 显示全部楼层 |阅读模式
    贪婪法,又称贪心法是一种不追求最优解,只希望得到较为满意解的方法。贪婪法一般可以快速得到满意的解,因为它省去了为找最优解要穷尽所有可能而必须耗费的大量时间。

        贪婪法常以当前情况为基础作最优选择,而不考虑各种可能的整体情况。

        例如平时购物找钱时,为使找回的零钱的硬币数最少,不考虑找零钱的所有各种方案,而是从最大面值的币种开始,按递减的顺序考虑各币种,先尽量用大面值的币种,当不足大面值币种的金额时才去考虑下一种较小面值的币种。这就是在使用贪婪法。这种方法在这里总是最优,是因为银行对其发行的硬币种类和硬币面值的巧妙安排。

        如只有面值分别为1、5和11单位的硬币,而希望找回总额为15单位的硬币。按贪婪算法,应找1个11单位面值的硬币和4个1单位面值的硬币,共找回5个硬币。但最优的解应是3个5单位面值的硬币。   
      
       
       
         
       

         
       
      
        【问题】 装箱问题
    问题描述:装箱问题可简述如下:设有编号为0、1、…、n-1的n种物品,体积分别为v0、v1、…、vn-1。将这n种物品装到容量都为V的若干箱子里。约定这n种物品的体积均不超过V,即对于0≤i<n,有0<vi≤V。不同的装箱方案所需要的箱子数目可能不同。装箱问题要求使装尽这n种物品的箱子数要少。

        对适当大的n,找出所有可能的划分要花费的时间是无法承受的。为此,对装箱问题采用非常简单的近似算法,即贪婪法。该算法依次将物品放到它第一个能放进去的箱子中,该算法虽不能保证找到最优解,但还是能找到非常好的解。不失一般性,设n件物品的体积是按从大到小排好序的,即有v0≥v1≥…≥vn-1。如不满足上述要求,只要先对这n件物品按它们的体积从大到小排序,然后按排序结果对物品重新编号即可。装箱算法简单描述如下:
    输入箱子的容积;
    输入物品种数n;
    按体积从大到小顺序,输入各物品的体积;
    预置已用箱子链为空;
    预置已用箱子计数器box_count为0;
    for (i=0;i<n;i++) {
         从已用的第一只箱子开始顺序寻找能放入物品i 的箱子j;
        if (已用箱子都不能再放物品i) {
          另用一个箱子,并将物品i放入该箱子;
          box_count++;
        } else
         将物品i放入箱子j;
        }
    }
    上述算法能求出需要的箱子数box_count,并能求出各箱子所装物品。但不一定能找到最优解,

    例:(北大百练题)
         一个工厂制造的产品形状都是长方体,它们的高度都是h,长和宽都相等,一共有六个型号,他们的长宽分别为1*1, 2*2, 3*3, 4*4, 5*5, 6*6。这些产品通常使用一个 6*6*h 的长方体包裹包装然后邮寄给客户。因为邮费很贵,所以工厂要想方设法的减小每个订单运送时的包裹数量。他们很需要有一个好的程序帮他们解决这个问题从而节省费用。现在这个程序由你来设计。  输入
    输入文件包括几行,每一行代表一个订单。每个订单里的一行包括六个整数,中间用空格隔开,分别为1*1至6*6这六种产品的数量。输入文件将以6个0组成的一行结尾。  输出
    除了输入的最后一行6个0以外,输入文件里每一行对应着输出文件的一行,每一行输出一个整数代表对应的订单所需的最小包裹数。

    样例输入
    0 0 4 0 0 1
    7 5 1 0 0 0
    0 0 0 0 0 0  样例输出
    2
    1  程序:
    1. import java.io.BufferedInputStream;   
    2. import java.util.Scanner;   
    3.   
    4. /**  
    5. * 分情况考虑贪心。关键是3*3的盒子怎么放。  
    6. * 6*6的放满整个盒子,  
    7. * 5*5的还可以放11个1*1。  
    8. * 4*4的还可以放5个2*2的。  
    9. * 3*3的总个数模4后,也就是说最后一个盒子放几个3*3的。  
    10. * 如果是1,还可以放5个2*2和7个1*1。  
    11. * 如果是2,可以放3个2*2和6个1*1。  
    12. * 如果是3,可以放1个2*2和5个1*1的。  
    13. * 2*2的模9就是最后一个箱子里放2*2的个数,36-(2*2的个数%9)就是可以放1*1的个数。  
    14. * 最后(1*1的个数+35)/36就是最后的盒子数。  
    15. * @author NC  
    16. */  
    17. public class Main {   
    18.   
    19.     public static void main(String[] args) {   
    20.         Scanner scan = new Scanner(new BufferedInputStream(System.in));   
    21.         while (scan.hasNext()) {   
    22.             int a1 = scan.nextInt();   
    23.             int a2 = scan.nextInt();   
    24.             int a3 = scan.nextInt();   
    25.             int a4 = scan.nextInt();   
    26.             int a5 = scan.nextInt();   
    27.             int a6 = scan.nextInt();   
    28.             if (a1 == 0 && a2 == 0 && a3 == 0 && a4 == 0 && a5 == 0 && a6 == 0) {   
    29.                 break;   
    30.             }   
    31.             int count = 0;   
    32.             if (a6 > 0) {   
    33.                 count += a6;   
    34.             }   
    35.             if (a5 > 0) {   
    36.                 count += a5;   
    37.                 a1 = a1 - a5 * 11;   
    38.             }   
    39.              while (a4 > 0) {   
    40.                 count++;   
    41.                 if (a2 >= 5) {   
    42.                     a2 -= 5;   
    43.                 } else {   
    44.                     a1 = a1 - (5 - a2) * 4;   
    45.                     a2 = 0;   
    46.                 }   
    47.                 a4--;   
    48.             }   
    49.             count += a3 / 4;   
    50.             a3 = a3 % 4;   
    51.             if (a3 > 0) {   
    52.                 count++;   
    53.                 if (a3 == 1) {   
    54.                     if (a2 >= 5) {   
    55.                         a2 -= 5;   
    56.                         a1 -= 7;   
    57.                     } else {   
    58.                         a1 = a1 - (5 - a2) * 4 - 7;   
    59.                         a2 = 0;   
    60.                     }   
    61.                 } else if (a3 == 2) {   
    62.                     if (a2 >= 3) {   
    63.                         a2 -= 3;   
    64.                         a1 -= 6;   
    65.                     } else {   
    66.                         a1 = a1 - (3 - a2) * 4 - 6;   
    67.                         a2 = 0;   
    68.                     }   
    69.                 } else if (a3 == 3) {   
    70.                     if (a2 >= 1) {   
    71.                         a2 -= 1;   
    72.                         a1 -= 5;   
    73.                     } else {   
    74.                         a1 = a1 - 4 - 5;   
    75.                         a2 = 0;   
    76.                     }   
    77.                 }   
    78.             }   
    79.             if (a2 > 0) {   
    80.                 count += a2 / 9;//最初时,犯了个超低级错误。。。。36(2*2)=18   
    81.                 a2 = a2 % 9;   
    82.                 if (a2 > 0) {   
    83.                     count++;   
    84.                     a1 = a1 - 4 * (9 - a2);   
    85.                 }   
    86.             }   
    87.   
    88.             if (a1 > 0) {   
    89.                 count += a1 / 36;   
    90.                 a1 = a1 % 36;   
    91.                 if (a1 > 0) {   
    92.                     count++;   
    93.                 }   
    94.             }   
    95.             System.out.println(count);   
    96.         }   
    97.     }   
    98. }  
    复制代码
      

      
      
       
       

         
       

         
       
      
    复制代码

    源码下载:http://file.javaxxz.com/2014/11/27/000521296.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 04:23 , Processed in 0.344493 second(s), 34 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表