1 条题解

  • 0
    @ 2025-8-24 23:14:40

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar _Null_Ptr
    ୧⍤⃝୨ ୧⌓̈⃝୨ ୧⍥⃝୨ ด้้้้้็้้้็็็็็้้้้้็็็็็้้้้้้็็็็็้้้้้็็็็็้้้้้้็็็็็้้้้้็็็็็้้้้้้็็็็็้้้้้็็็็็้้้้้้็็ ୧⍤⃝ ୧⍤⃝ ୧⍤⃝୧⍤⃝

    搬运于2025-08-24 23:14:40,当前版本为作者最后更新于2025-04-25 20:38:44,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    蓝桥杯2023省赛Java B组「最大开支」题解

    本题的关键在于每次分配人员时,选择能使‌边际收益‌最大的项目(边际收益指的是当前项目增加一人带来的花费增量)。

    由题意得,对于项目 ii,当已有 xix_i 人时:

    • 当前总花费:kixi2+bixik_ix_i^{2} + b_ix_i

    • 增加一人后的总花费:ki×(xi+1)2+bi×(xi+1)k_i\times(x_i+1)^{2} + b_i\times(x_i+1)

    • 边际收益:$[k_i\times(x_i+1)^{2} + b_i\times(x_i+1)] - (k_ix_i^{2} + b_ix_i) = k_i\times(2x_i + 1) + b_i$

    故可以使用‌最大堆‌来动态维护各项目的边际收益,每次取出边际收益最大的项目进行分配,然后更新该项目的边际收益。

    下面贴上代码,注意看数据范围,记得开 long long。

    #include <iostream>
    #include <queue>
    #define int long long 
    using namespace std;
    struct p {
        int k,b,x,ic;
        bool operator<(const p& other) const {return ic < other.ic; }
    }; 
    priority_queue<p> pq;
    int n, m, k, b, anss;
    main() {
        cin>>n>>m;
        for (int i=1;i<=m;i++) {
            cin >> k >> b;
            int icc = k+b;
            if (icc>0) pq.push({k, b, 0, icc});
        }
        int rm=n;
        while (rm>0&&!pq.empty()) {
            p curr = pq.top();
            pq.pop();
            anss += curr.ic;rm--;
            int new_x = curr.x + 1,newi=curr.k*(2*new_x+1)+curr.b;
            if (newi > 0) pq.push({curr.k,curr.b,new_x,newi});
        }
        
        cout<<anss<<endl;
    }
    
    
    import java.util.PriorityQueue;
    import java.util.Scanner;
    
    class P implements Comparable<P> {
        long k;
        long b;
        long x;
        long ic;
    
        public P(long k, long b, long x, long ic) {
            this.k = k;
            this.b = b;
            this.x = x;
            this.ic = ic;
        }
    
        @Override
        public int compareTo(P other) {
            return Long.compare(other.ic, this.ic);
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            Scanner scanner = new Scanner(System.in);
            long n = scanner.nextLong();
            long m = scanner.nextLong();
    
            PriorityQueue<P> pq = new PriorityQueue<>();
            long anss = 0;
    
            for (int i = 1; i <= m; i++) {
                long k = scanner.nextLong();
                long b = scanner.nextLong();
                long icc = k + b;
                if (icc > 0) {
                    pq.add(new P(k, b, 0, icc));
                }
            }
    
            long rm = n;
            while (rm > 0 && !pq.isEmpty()) {
                P curr = pq.poll();
                anss += curr.ic;
                rm--;
                long new_x = curr.x + 1;
                long newi = curr.k * (2 * new_x + 1) + curr.b;
                if (newi > 0) {
                    pq.add(new P(curr.k, curr.b, new_x, newi));
                }
            }
    
            System.out.println(anss);
            scanner.close();
        }
    }    
    
    • 1

    信息

    ID
    12169
    时间
    2000ms
    内存
    512MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者