zoukankan      html  css  js  c++  java
  • 洛谷P2085《最小函数值》

    解题报告

    事见过的套路


    首先可以发现符合题意的函数对称轴都在二三象限,也就是说这些函数都是在第一象限单增的

    所以我们可以知道:(x = 1) 时所有的函数都能取到最小值

    先把这些值扔进数组里。一会我们挨个输出数组里的最小值,然后把这个值删掉。

    可以发现,在输出当前的最小值之后,下一个更大的值要么来源于当前的数组中,要么来源于这个函数的下一个值。于是我们就可以把这个函数的下一个值也扔进当前的数组中,然后排序取值。

    于是我们算法的过程就是:

    • 取出所有的 (x = 1)
    • 找最小值输出,删掉这个最小值
    • 把这个最小值对应函数的下一个值取出
    • 继续找最小值输出,删掉这个最小值
    • 把这个最小值对应函数的下一个值取出……

    这个过程可以用堆实现,时间复杂度 (O(mlog n))

    代码实现

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <queue>
    
    #define forall(G,i) for (int i = 0, __for_siz__ = (int) (G).size(); i < __for_siz__; ++i) 
    #define DEBUG(x) std::cerr << #x << " = " << x << std::endl;
    #define ALL(x) (x).begin(), (x).end()
    #define MP std::make_pair
    #define se second
    #define fi first
    
    using std::cin;
    using std::cout;
    using std::endl;
    
    inline int read() {
        int s = 0, x = 1; char ch = getchar();
        while (!isdigit(ch)) { if (ch == '-') x = -x; ch = getchar(); }
        while (isdigit(ch)) { s = s * 10 + ch - '0'; ch = getchar(); }
        return s * x;
    }
    
    const int MAXN = 10000 + 10;
    
    struct Func {
        int a, b, c, x;
        Func(int _a = 0, int _b = 0, int _c = 0) :
            a(_a), b(_b), c(_c), x(1) {}
        int get() { return a * x * x + b * x + c; }
    } func[MAXN];
    
    // 所有函数在 x 正半轴上都是单增的
    
    int n, m;
    
    std::priority_queue<std::pair<int, int>, std::vector<std::pair<int, int> >, std::greater<std::pair<int, int> > > q;
    
    int main() {
        n = read(); m = read();
        for (int i = 1; i <= n; ++i) {
            int a = read(); int b = read(); int c = read();
            func[i] = Func(a, b, c);
            q.push(MP(func[i].get(), i)); // 每个函数的最小函数值 (x = 1)
        }
        for (int i = 1; i <= m; ++i) {
            printf("%d%c", q.top().first, i == m ? '
    ' : ' '); // 这些最小值里的最小值
            int now = q.top().second; // 该最小值对应的函数
            q.pop();
            ++func[now].x; q.push(MP(func[now].get(), now)); // 取出它的下一个函数值
        }
        return 0;
    }
    
  • 相关阅读:
    LeetCode Binary Tree Inorder Traversal
    LeetCode Populating Next Right Pointers in Each Node
    LeetCode Construct Binary Tree from Inorder and Postorder Traversal
    LeetCode Reverse Linked List II
    LeetCode Populating Next Right Pointers in Each Node II
    LeetCode Pascal's Triangle
    Palindrome Construct Binary Tree from Preorder and Inorder Traversal
    Pascal's Triangle II
    LeetCode Word Ladder
    LeetCode Binary Tree Zigzag Level Order Traversal
  • 原文地址:https://www.cnblogs.com/handwer/p/14681358.html
Copyright © 2011-2022 走看看