P2085 最小函数值——小顶堆、贪心、重载运算符

题目描述

\(n\) 个函数,分别为 \(F_1,F_2,\dots,F_n\)。定义 \(F_i(x)=A_ix^2+B_ix+C_i(x\in\mathbb N*)\)。给定这些 \(A_i\)\(B_i\)\(C_i\),请求出所有函数的所有函数值中最小的 \(m\) 个(如有重复的要输出多个)。

输入格式

第一行输入两个正整数 \(n\)\(m\)

以下 \(n\) 行每行三个正整数,其中第 \(i\) 行的三个数分别为 \(A_i\)\(B_i\)\(C_i\)

输出格式

输出将这 \(n\) 个函数所有可以生成的函数值排序后的前 \(m\) 个元素。这 \(m\) 个数应该输出到一行,用空格隔开。

输入输出样例 #1

输入 #1

3 10
4 5 3
3 4 5
1 7 1

输出 #1

9 12 12 19 25 29 31 44 45 54

说明/提示

数据规模与约定

对于全部的测试点,保证 \(1 \leq n,m\le10000\)\(1 \leq A_i\le10,B_i\le100,C_i\le10^4\)

题解

#include <iostream>
#include <queue>
#include <vector>
using namespace std;

// 定义结构体存储函数值、函数编号和当前 x 值
struct Node {
    int value;  // 函数值
    int funcIndex;  // 函数编号
    int x;  // 当前 x 值
    // 重载运算符,用于优先队列的比较
    bool operator>(const Node& other) const {
        return value > other.value;
    }
};

int main() {
    int n, m;
    cin >> n >> m;

    // 存储每个函数的 A, B, C 参数
    vector<vector<int>> functions(n, vector<int>(3));
    for (int i = 0; i < n; ++i) {
        cin >> functions[i][0] >> functions[i][1] >> functions[i][2];
    }

    // 定义小根堆
    priority_queue<Node, vector<Node>, greater<Node>> heap;

    // 初始化小根堆
    for (int i = 0; i < n; ++i) {
        int A = functions[i][0];
        int B = functions[i][1];
        int C = functions[i][2];
        // 计算 x = 1 时的函数值
        int value = A * 1 * 1 + B * 1 + C;
        // 将 (函数值, 函数编号, 当前 x 值) 加入堆
        heap.push({value, i, 1});
    }

    // 存储结果
    vector<int> result;
    // 进行 m 次操作
    for (int i = 0; i < m; ++i) {
        // 取出堆中最小的函数值
        Node top = heap.top();
        heap.pop();
        result.push_back(top.value);
        // 计算下一个 x 值对应的函数值
        int A = functions[top.funcIndex][0];
        int B = functions[top.funcIndex][1];
        int C = functions[top.funcIndex][2];
        int nextX = top.x + 1;
        int nextValue = A * nextX * nextX + B * nextX + C;
        // 将新的函数值加入堆
        heap.push({nextValue, top.funcIndex, nextX});
    }

    // 输出结果
    for (int i = 0; i < m; ++i) {
        if (i > 0) {
            cout << " ";
        }
        cout << result[i];
    }
    cout << endl;

    return 0;
}

贪心策略

posted @ 2025-02-24 21:10  ToFuture$  阅读(25)  评论(0)    收藏  举报