zoukankan      html  css  js  c++  java
  • 【NOIP2012提高组】国王游戏 贪心 + 高精度

    题目分析

    题目答案不具有单调性,所以不可以二分,转而思考贪心。因为无法确定位置,所以考虑如何才能让对于每一个$1 ~ i$使得$i$的答案最大,即$1 ~ i$最后一个最优。若设对于位置$i$,$a[i]$表示左手,$b[i]$表示右手,$S$为其前面所有人的左手之积,那么他的答案就是$frac{S}{b[i]}$,如果存在在$i$后边的$j$的答案更优, 即$frac{S * a[i]}{b[j]} > frac{S * a[j]}{b[i]} => a[i] * b[i] > a[j] * b[j]$,这样只要我们以a[i] * b[i]为关键字从小到大排序,就能保证每个前缀的最后一个都是最优的,只要$o(n)$扫一遍取最大值即可,记得使用高精度。

    code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    
    const int N = 1050;
    int n, a[N], b[N], c[N], ka, kb, kc;
    
    inline int read(){
        int i = 0, f = 1; char ch = getchar();
        for(; (ch < '0' || ch > '9') && ch != '-'; ch = getchar());
        if(ch == '-') f = -1, ch = getchar();
        for(; ch >= '0' && ch <= '9'; ch = getchar())
            i = (i << 3) + (i << 1) + (ch - '0');
        return i * f;
    }
    
    inline void wr(int x){
        if(x < 0) putchar('-'), x = -x;
        if(x > 9) wr(x / 10);
        putchar(x % 10 + '0');
    }
    
    struct bign{
        int len, s[10000];
        bign():len(0){memset(s, 0, sizeof s);}
        bign(int x):len(0){
            memset(s, 0, sizeof s);
            while(x){
                s[++len] = x % 10;
                x /= 10;
            }
            if(!len) len = 1;
        }
        inline void clear(){
            while(len > 1 && s[len] == 0) len--;
        }
        inline bign operator * (const bign &b) const{
            bign ret;
            ret.len = len + b.len + 5;
            for(int i = 1; i <= len; i++)
                for(int j = 1; j <= b.len; j++)
                    ret.s[i + j - 1] += s[i] * b.s[j];
            for(int i = 1; i <= ret.len; i++)
                if(ret.s[i] >= 10){
                    ret.s[i + 1] += ret.s[i] / 10;
                    ret.s[i] %= 10;
                }
            ret.clear();
            return ret;
        }
        inline bign operator - (const bign &b) const{
            bign ret;
            ret.len = len;
            for(int i = 1; i <= len; i++){
                ret.s[i] = ret.s[i] + s[i];
                if(i <= b.len) ret.s[i] = ret.s[i] - b.s[i];
                if(ret.s[i] < 0){
                    ret.s[i + 1]--;
                    ret.s[i] += 10;
                }
            }
            ret.clear();
            return ret;
        }
        bign operator / (int b) {
            bign c;
            int f = 0;
            for(int i = len; i >= 1; i--){
                f = f * 10 + s[i];
                while(!(f < b)){
                    f -= b;
                    c.s[i]++;
                }
            }
            c.len = len;
            c.clear();
            return c;
        }
        inline bool operator > (const bign &b) const{
            if(len != b.len) return len > b.len;
            for(int i = len; i >= 1; i--)
                if(s[i] != b.s[i]) return s[i] > b.s[i];
            return false;
        }
        inline bool operator == (const bign &b) const{
            if(len != b.len) return false;
            for(int i = len; i >= 1; i--)
                if(s[i] != b.s[i]) return false;
            return true;
        }
        inline bool operator < (const bign &b) const{
            if(len != b.len) return len < b.len;
            for(int i = len; i >= 1; i--)
                if(s[i] != b.s[i]) return s[i] < b.s[i];
            return false;
        }
        inline void print(){
            for(int i = len; i >= 1; i--)
                wr(s[i]);
        }
    }fa, ans, big0, big10;
    
    struct node{
        int a, b, c;
        inline bool operator < (const node &u) const{
            if(c != u.c) return c < u.c;
            return b > u.b;
        }
    }data[N];
    
    int main(){
        n = read(), ka = read(), kb = read();
        for(int i = 1; i<= n; i++){
            data[i].a = read(), data[i].b = read();
            data[i].c = data[i].a * data[i].b;
        }
        sort(data + 1, data + n + 1);
        fa = ka;
        ans = 0;
        bign tmpa, t;
        for(int i = 1; i <= n; i++){
            tmpa = data[i].a;
            t = fa / data[i].b;
            if(t > ans) ans = t;
            fa = fa * tmpa;
        }
        ans.print();
        return 0;
    }
  • 相关阅读:
    PTA 程序设计题(数据结构第一章)
    (考研)计算机组成原理之计算机系统概论
    C语言复习
    vs2019 scanf 解决 C4996问题
    数据结构之链表
    数据结构之表、栈、队列
    数据结构之算法分析
    数据结构泛型之初接触
    数据结构之递归
    学习参考
  • 原文地址:https://www.cnblogs.com/CzYoL/p/7429524.html
Copyright © 2011-2022 走看看