• 贪心算法(2)--衍生问题


    目录

    一、会场安排问题

    1、算法概述

    2、代码

    二、最优服务次序问题

    1、算法概述

    2、代码

    三、虚拟汽车加油问题

    1、算法概述

    2、代码

    四、 最优分解问题

    1、算法概述

    2、代码 


    一、会场安排问题

    1、算法概述

            会场安排问题:假设要在足够多的会场安排一批活动,并希望使用尽可能少的会场,设计一个有效的贪心算法,进行安排。(其实就是前面的活动安排问题的衍生问题)

            算法:按照结束时间排序优先进行贪心算法,与活动安排不同的点在于,每当计算一次活动安排问题时,就要添加一个会场,之后也不需要再计算这个活动。

            参数表:

                    s[ ]:活动开始时间

                    f[ ]:活动结束时间

                    exist[ ]:当前会场是否使用,使用为1,未使用为0

                    room[ ]:room[0]计算会场个数,room[1]计算当前未执行的活动个数,若为0则退出遍历。

    2、代码

    1. import java.util.Scanner;
    2. //会场安排问题
    3. public class conferencearrangement {
    4. public static void main(String[] args)
    5. {
    6. int n=new Scanner(System.in).nextInt();
    7. int s[]=new int[n];
    8. int f[]=new int[n];
    9. int exist[]=new int[n];
    10. int i;
    11. for(i=0;i
    12. {
    13. String input=new Scanner(System.in).nextLine();
    14. String []numbers=input.split("\\s+");
    15. s[i]=Integer.parseInt(numbers[0]);
    16. f[i]=Integer.parseInt(numbers[1]);
    17. }
    18. quickSort(f,s, 0, n-1);
    19. int room[]={0,n};
    20. while(true)
    21. {
    22. if(room[1]==0)
    23. break;
    24. GreedySelector(s,f,room,exist);
    25. }
    26. System.out.println(room[0]);
    27. }
    28. public static void GreedySelector(int s[],int f[],int room[],int exist[])
    29. {
    30. int begin;int index=999;int end=999;
    31. for(int i=0;i
    32. {
    33. if(exist[i]==0)
    34. {
    35. begin=s[i];
    36. end=f[i];
    37. exist[i]=1;
    38. index=i;
    39. room[1]-=1;
    40. break;
    41. }
    42. }
    43. for(int j=index+1;j
    44. {
    45. if((exist[j]==0)&&(end<=s[j]))
    46. {
    47. begin=f[j];
    48. end=s[j];
    49. exist[j]=1;
    50. room[1]-=1;
    51. }
    52. }
    53. room[0]+=1;
    54. }
    55. public static void quickSort(int[] arr,int[] s,int low,int high){
    56. int i=low; int j=high; int temp,t;
    57. if(low>high){
    58. return;
    59. }
    60. //temp就是基准位
    61. temp = arr[low];
    62. while (i
    63. while (temp<=arr[j]&&i//右哨兵减一
    64. while (temp>=arr[i]&&i//左哨兵加一
    65. if (i//交换
    66. t = arr[j];
    67. arr[j] = arr[i];
    68. arr[i] = t;
    69. t = s[j];
    70. s[j] = s[i];
    71. s[i] = t;
    72. }
    73. }
    74. arr[low] = arr[i]; //将基准为与i和j相等位置的数字交换
    75. arr[i] = temp;
    76. int tmp_s=s[low];s[low]=s[i];s[i]=tmp_s;
    77. quickSort(arr, s,low, j-1); //递归调用左半数组
    78. quickSort(arr,s, j+1, high); //递归调用右半数组
    79. }
    80. }

    测试用例: 

    1. //输入
    2. 5
    3. 1 23
    4. 12 28
    5. 25 35
    6. 27 80
    7. 36 50
    8. //输出
    9. 3

    二、最优服务次序问题

    1、算法概述

            最优服务次序问题:设有n个顾客同时等待一项服务,顾客i需要的服务时间是t_i,应如何安排n个顾客的服务次序才能使平均等待时间达到最小。

            算法:贪心算法,由于n个顾客同时开始等待,则开始时间都为0时刻,服务时间为t_i,结束时间为分别为前一个人i的结束时间e_i加上t_i。所以我们可以对服务时间排序,让服务时间最短的优先服务。

            平均等待时间=\sum_{i=0}^{arr.length-1} arr[i]*(n-i),其中arr数组为按服务时间由短到长排序的数组。

    2、代码

    1. public static void main(String args[])
    2. {
    3. int n=10;double total=0;
    4. int arr[]={56,12,1,99,1000,234,33,55,99,812};
    5. quickSort(arr, 0, arr.length-1);
    6. System.out.println(arr[0]);
    7. for(int i=0;i
    8. {
    9. total+=arr[i]*(n-i);
    10. }
    11. System.out.println(total/10);
    12. }
    13. public static void quickSort(int[] arr,int low,int high){
    14. int i=low; int j=high; int temp,t;
    15. if(low>high){
    16. return;
    17. }
    18. temp = arr[low];
    19. while (i
    20. while (temp<=arr[j]&&i
    21. while (temp>=arr[i]&&i
    22. if (i
    23. t = arr[j];
    24. arr[j] = arr[i];
    25. arr[i] = t;
    26. }
    27. }
    28. arr[low] = arr[i];
    29. arr[i] = temp;
    30. quickSort(arr, low, j-1);
    31. quickSort(arr, j+1, high);
    32. }

    三、虚拟汽车加油问题

    1、算法概述

            虚拟汽车加油问题:一辆虚拟汽车加满油后可行驶nkm,旅途中有k个加油站,给出起点、相邻加油站、终点之间的距离,所有点位都共线,设计一个算法,指出在哪些加油站停靠加油,使沿途加油次数最少,并产生一个最优解。

            算法:贪心算法,只需要判断汽车油箱还能不能开过这一段距离,否则立刻加油,如果能开过这一段距离则不需要加油。

    2、代码

    1. //汽车加油问题
    2. public class vehiclerefuel {
    3. public static void main(String args[])
    4. {
    5. int n=7;
    6. int k=7;
    7. int arr[]={1,2,3,4,5,1,6,6};
    8. System.out.println(refuel(n,arr));
    9. }
    10. public static int refuel(int n,int arr[])
    11. {
    12. int count=0;
    13. for(int i=0;i
    14. {
    15. if(n>=arr[i])
    16. n-=arr[i];
    17. else
    18. {
    19. n=arr.length;
    20. n-=arr[i];
    21. count+=1;
    22. }
    23. }
    24. return count;
    25. }
    26. }

    四、 最优分解问题

    1、算法概述

            最优分解问题:设n是一个正整数,现在要将n分解为若干互不相同的自然数之和,且这些自然数的乘积最大。

            算法:贪心算法,这道题的贪心很巧妙,简称对半分,如果这个数n是奇数,则中间两个数相乘为最大值,若n为偶数,则中间的数与n-n/2的拆分的最大值的乘积为最大值。其实内部的这种子问题重叠的效果,有点类似于动态规划。

            整数分解中有这条性质:若 a + b = const,则 |a - b| 越小,a·b越大。

    bestdivide(x)=\begin{Bmatrix} \left \lfloor \frac{x}{2} \right \rfloor \times(\left \lfloor \frac{x}{2} \right \rfloor+1) \qquad \quad x$\%$2==0 \\ \left \lfloor \frac{x}{2} \right \rfloor \times bestdivide(\left \lfloor \frac{x}{2} \right \rfloor \quad x$\%$2\neq 0) \end{Bmatrix}

    2、代码 

    1. import java.util.Scanner;
    2. import java.util.ArrayList;
    3. //最优分解问题
    4. public class bestdivide {
    5. public static void main(String[] args)
    6. {
    7. int n=new Scanner(System.in).nextInt();
    8. ArrayList arr=new ArrayList<>();
    9. int tot=1;
    10. divide(n,arr);
    11. for(int num:arr)
    12. tot*=num;
    13. System.out.println(tot);
    14. }
    15. public static void divide(int n,ArrayListarr)
    16. {
    17. int tmp=0;
    18. while(true)
    19. {
    20. if(n%2!=0)
    21. {
    22. arr.add(n/2);
    23. arr.add(n-n/2);
    24. break;
    25. }
    26. else
    27. {
    28. arr.add(n/2);
    29. n=n/2;
    30. }
    31. }
    32. }
    33. }
  • 相关阅读:
    mmdetection最新版食用教程(一):安装并运行demo及开始训练coco
    3.3-3.6二叉树专题
    nginx反向代理
    力扣面试 150二叉搜索树迭代器 中序遍历 栈模拟递归 步骤拆分
    vue中实现文件批量打包压缩下载(以及下载跨域问题分析)
    2023临沂大学计算机考研信息汇总
    信息学奥赛一本通:1156:求π的值
    GCC多平台编译会遇到小问题
    win10卸载oracle11g
    【linux驱动开发】-关于驱动学习你得知道的
  • 原文地址:https://blog.csdn.net/m0_60177079/article/details/133966945