题解:P12331 [蓝桥杯 2023 省 Java B] 最大开支

· · 题解

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

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

由题意得,对于项目 i,当已有 x_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();
    }
}