餐馆

某餐馆有n张桌子,每张桌子有一个参数:a 可容纳的最大人数; 有m批客人,每批客人有两个参数:b人数,c预计消费金额。 在不允许拼桌的情况下,请实现一个算法选择其中一部分客人,使得总预计消费金额最大
输入描述:

输入包括m+2行。 第一行两个整数n(1 <= n <= 50000),m(1 <= m <= 50000) 第二行为n个参数a,即每个桌子可容纳的最大人数,以空格分隔,范围均在32位int范围内。 接下来m行,每行两个参数b,c。分别表示第i批客人的人数和预计消费金额,以空格分隔,范围均在32位int范围内。

输出描述:

输出一个整数,表示最大的总预计消费金额
示例1
输入

3 5 2 4 2 1 3 3 5 3 7 5 9 1 10

输出

20

import java.util.*;
public class Restaurant{
 public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()){
        int n = sc.nextInt(); // n table
        int m = sc.nextInt();// m customers
        int[] table = new int[n];
        for(int i = 0;i < n;i++)
        table[i] = sc.nextInt();// volume of a table
        int[][] cus = new int[m][2];
        for(int j = 0;j < m;j++){
        cus[j][0] = sc.nextInt(); // number of customers
        cus[j][1] = sc.nextInt(); // money
        }
            Arrays.sort(table);
            Arrays.sort(cus, new Comparator<int[]>(){//通过自定义比较器实现逆序排序
            public int compare(int[] a, int[] b){    //老师上课提问过。看到这段代码才明白
            return b[1]-a[1]; //三种情况缩写,想起了c语言strcmp1的return (*p1 - *p2); 返回值大于0然后b[1]放在a[1]前面
                            }
            });//这批人只是逆序本身预估值,按预估值来尽可能安排座位实现贪心,而非单人比值,因为一个桌子一批人
            long res = 0L;
            int index = 0;
            boolean[] tableb = new boolean[n];
            for(int i = 0;i < m;i++){
            if(cus[i][0] > table[n-1])
            continue; //如果最大容量桌子都容不下,就执行下次循环
            index = bs(table,cus[i][0]);
            while(index < n && tableb[index] == true)
            index++;//判断标记,一旦桌子有人就往后
            if(index < n){
            res += cus[i][1];//累计预估资金值
            tableb[index] = true;
            }
    }
      System.out.println(res);
  }
  sc.close();
}
     private static int bs(int[] num, int tar){//二分法 查找合适的桌子
        int low = 0;
        int high = num.length-1;
        int mid = 0;
        while(low <= high){
            mid = (high + low)>>1;//右移操作 除2
            if(num[mid] >= tar)
            high = mid-1; //能容下就左边再二分查找
            else
            low = mid+1;//容不下
        }
        return low;//返回low的下标,尽可能用合适(升序)的容量去容下当前尽可能大(降序)的预估值的一批人
        }
}

题 目 有一定 难度,自己没写出来(时间问题),借鉴了的大佬的写法,在这里存下档(个人理解)。希望大佬的解法对有疑惑的小伙伴能提供帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值