贪心算法——埃及分数问题

贪心算法之埃及分数问题

一、问题描述

把一个真分数表示成最少的埃及分数之和。

埃及分数即分子为1的分数。


二、问题分析

1、贪心算法的思想在本问题中的体现为在每一步的分解中都寻找最大的埃及分数。

2、具体步骤如下

步骤一

假设真分数N/M的分子为N,分母为M,则有下式成立

M = K * N + Z,其中Z必小于N

两边同时除以分子N后,可知

M/N = K + Z/N < K + 1

所以,必有下式成立

N/M > 1/K+1

所以,小于真分数N/M的最大埃及分数为1/K+1。

步骤二

下一步再寻找N/M - 1/K+1的最大埃及分数,通分后也即寻找真分数(N*(K+1) - M)/M*(K+1)的最大埃及分数。

在开始之前,需要先把(N*(K+1) - M)/M*(K+1)约分,也即寻找分子与分母的最大公约数,详见博文两正整数最大公约数

约分之后再按步骤一的解法寻找最大埃及分数。

步骤三

步骤一和步骤二循环执行,直到分子为1。


三、算法代码


 
 
  1. public void egyptFraction(int num1, int num2){
  2. int trade = 0;
  3. int maxComDiv = 0;
  4. while(num1 > 1){
  5. trade = num2 / num1 + 1;
  6. System.out.println( 1 + "/" + trade);
  7. num1 = num1 * trade - num2;
  8. num2 = num2 * trade;
  9. maxComDiv = maxComDiv(num1, num2);
  10. if(maxComDiv > 1){
  11. num1 = num1 / maxComDiv;
  12. num2 = num2 / maxComDiv;
  13. }
  14. }
  15. System.out.println( 1 + "/" + num2);
  16. }
  17. public int maxComDiv(int num1, int num2) {
  18. int remaind = 0;
  19. while(num2 != 0){
  20. remaind = num1 % num2;
  21. num1 = num2;
  22. num2 = remaind;
  23. }
  24. return num1;
  25. }
四、完整测试代码


 
 
  1. public class Solution {
  2. public static void main(String [] args){
  3. int nums1 = 2;
  4. int nums2 = 3;
  5. egyptFraction(nums1, nums2);
  6. }
  7. public static void egyptFraction(int num1, int num2){
  8. int trade = 0;
  9. int maxComDiv = 0;
  10. while(num1 > 1){
  11. trade = num2 / num1 + 1;
  12. System.out.println( 1 + "/" + trade);
  13. num1 = num1 * trade - num2;
  14. num2 = num2 * trade;
  15. maxComDiv = maxComDiv(num1, num2);
  16. if(maxComDiv > 1){
  17. num1 = num1 / maxComDiv;
  18. num2 = num2 / maxComDiv;
  19. }
  20. }
  21. System.out.println( 1 + "/" + num2);
  22. }
  23. public static int maxComDiv(int num1, int num2) {
  24. int remaind = 0;
  25. while(num2 != 0){
  26. remaind = num1 % num2;
  27. num1 = num2;
  28. num2 = remaind;
  29. }
  30. return num1;
  31. }
  32. }

五、运行结果

1/2
1/3
1/24




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

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

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

    余额充值