优先队列(二分查找优化)Java

此文章用于个人学习

Java PriorityQueue类是一种队列数据结构实现,其中根据优先级处理对象。它与遵循FIFO(先进先出)算法的标准队列不同。
在优先级队列中,添加的对象根据其优先级。默认情况下,优先级由对象的自然顺序决定。队列构建时提供的比较器可以覆盖默认优先级。
参考链接:https://blog.csdn.net/u010675669/article/details/86503464

PriorityQueue功能

让我们记下PriorityQueue上的几个要点。

  • PriorityQueue是一个无限制的队列,并且动态增长。默认初始容量’11’可以使用相应构造函数中的initialCapacity参数覆盖。
  • 它不允许NULL对象。
  • 添加到PriorityQueue的对象必须具有可比性。
  • 默认情况下,优先级队列的对象按自然顺序排序。
  • 比较器可用于队列中对象的自定义排序。
  • 优先级队列的头部是基于自然排序或基于比较器的排序的最小元素。当我们轮询队列时,它从队列中返回头对象。
  • 如果存在多个具有相同优先级的对象,则它可以随机轮询其中任何一个。
  • PriorityQueue 不是线程安全的。PriorityBlockingQueue在并发环境中使用。
  • 它为add和poll方法提供了O(log(n))时间。

优先队列构造函数

PriorityQueue类提供了6种在Java中构造优先级队列的方法。

  • PriorityQueue():使用默认初始容量(11)构造空队列,该容量根据其自然顺序对其元素进行排序。
  • PriorityQueue(Collection c):构造包含指定集合中元素的空队列。
  • PriorityQueue(int initialCapacity):构造具有指定初始容量的空队列,该容量根据其自然顺序对其元素进行排序。
  • PriorityQueue(int initialCapacity,Comparator comparator):构造具有指定初始容量的空队列,该容量根据指定的比较器对其元素进行排序。
  • PriorityQueue(PriorityQueue c):构造包含指定优先级队列中元素的空队列。
  • PriorityQueue(SortedSet c):构造包含指定有序集合中元素的空队列。

Java PriorityQueue方法

PriorityQueue类下面给出了重要的方法,你应该知道。

  • boolean add(object):将指定的元素插入此优先级队列。
  • boolean offer(object):将指定的元素插入此优先级队列。
  • boolean remove(object):从此队列中删除指定元素的单个实例(如果存在)。
  • Object poll():检索并删除此队列的头部,如果此队列为空,则返回null。
  • Object element():检索但不删除此队列的头部,如果此队列为空,则返回null。
  • Object peek():检索但不删除此队列的头部,如果此队列为空,则返回null。
  • void clear():从此优先级队列中删除所有元素。
  • Comparator comparator():返回用于对此队列中的元素进行排序的比较器,如果此队列根据其元素的自然顺序排序,则返回null。
  • boolean contains(Object o):如果此队列包含指定的元素,则返回true。
  • Iterator iterator():返回此队列中元素的迭代器。
  • int size():返回此队列中的元素数。
  • Object [] toArray():返回包含此队列中所有元素的数组。

优先队列代码

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
public class Main{
    //定义比较器
    static Comparator<skill> sk = new Comparator<skill>() {
        public int compare(skill s1,skill s2) {
            return s2.a - s1.a;//由大到小出队
        }
    };
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StreamTokenizer st = new StreamTokenizer(br);
    static int nextInt() throws Exception {st.nextToken();return (int) st.nval;}
    static int nextLong() throws Exception {st.nextToken();return (int) st.nval;}
    static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
    public static void main(String args[]) throws Exception {
        long sum = 0;
        skill s = new skill(0, 0); 
        int n = nextInt();
        int m = nextInt();
        Queue<skill> queue = new PriorityQueue<>(sk);
        for(int i=0;i<n;i++) {
            int a = nextInt();
            int b = nextInt();
            queue.offer(new skill(a, b));
        }
        for(int i=0;i<m;i++) {
            s = queue.poll();
            if(s.a==0)
                break;
            sum += s.a;
            if(s.a-s.b>0)
                queue.offer(new skill(s.a-s.b, s.b));
        }
        pw.print(sum);
        pw.flush();
    }
    static class skill{
        int a;
        int b;
        public skill(int a,int b) {
            this.a = a;
            this.b = b;
        }
    }
}

二分查找代码

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.*;
public class Main{
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StreamTokenizer st = new StreamTokenizer(br);
    static int nextInt() throws Exception {st.nextToken();return (int) st.nval;}
    static long nextIong() throws Exception {st.nextToken();return (long) st.nval;}
    static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
    public static void main(String args[]) throws Exception {
        int n = nextInt();
        long m = nextIong();
        int A[] = new int[100005];
        int B[] = new int[100005];
        for(int i=0;i<n;i++) {
            int a = nextInt();
            int b = nextInt();
            A[i] = a;
            B[i] = b;
        }
        int low = 0;
        int high = 1000000;
        while(low<high) {
            int mid = (low+high+1)/2;
            if(Tongji(A, B, mid, n)>=m) {
                low = mid;
            }
            else {
                high = mid-1;
            }
        }
        long sum = 0;
        for(int i=0;i<n;i++) {
            long x = 0;
            if(A[i]>=low) {
                x+=(A[i]-low)/B[i]+1;
                sum+=(A[i]+A[i]-(x-1)*B[i])*x/2;
            }
        }
        System.out.println(sum-(Tongji(A, B, low, n)-m)*low);
    }
    public static long Tongji(int a[],int b[],int c,int n) {
        long sum = 0;
        for(int i=0;i<n;i++) {
            if(a[i]>=c) {
                sum+=(a[i]-c)/b[i]+1;
            }
        }
        return sum;
    }
}
  • 11
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值