zoukankan      html  css  js  c++  java
  • 国王游戏

    【问题描述】

    恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右 手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 n 位大臣排 成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每 位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右 手上的数,然后向下取整得到的结果。 国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序, 使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。

    【输入】

    输入文件为 game.in。

    第一行包含一个整数 n,表示大臣的人数。 第二行包含两个整数 a和b,之间用一个空格隔开,分别表示国王左手和右手上的整数。

    接下来 n 行,每行包含两个整数 a 和 b,之间用一个空格隔开,分别表示每个大臣左手 和右手上的整数。

    【输出】

    输出文件名为 game.out。

    输出只有一行,包含一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的金币数。

    【输入输出样例】

    game.in

    3

    1 1

    2 3

    7 4

    4 6

    game.out  

    2

    【输入输出样例说明】

    按 1、2、3 号大臣这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

    按 1、3、2 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

    按 2、1、3 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

    按 2、3、1 这样排列队伍,获得奖赏最多的大臣所获得金币数为 9;

    按 3、1、2 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2;

    按 3、2、1 这样排列队伍,获得奖赏最多的大臣所获得金币数为 9。

    因此,奖赏最多的大臣最少获得 2 个金币,答案输出 2。

    【数据范围】 对于 20%的数据,有 1≤ n≤ 10,0 < a、b < 8;

    对于 40%的数据,有 1≤ n≤20,0 < a、b < 8;

    对于 60%的数据,有 1≤ n≤100; 对于 60%的数据,保证答案不超过 109;

    对于 100%的数据,有 1 ≤ n ≤1,000,0 < a、b < 10000。


    思路:

    非要证明的话还是挺抽象的,比较难理解,但举反例就很 clear .

    1. 如果一个大臣,左手的数字非常大,要满足国王,我们就要尽可能地把他往后放,让他左手数字的作用发挥的最小

    2. 如果一个大臣,右手的数字非常大,要满足国王,我们也要把他尽可能地往后放,让他右手的数字发挥的作用最大

    所以呢,左手右手其实是互相成正比的,就设 f[i] = l[i]*r[i] 

    以 f[i] 排升序,就是一个最优的队列(之一)

    20分的全排列

    #include<stdio.h>
    #include<string.h>
    #include<algorithm> 
    using namespace std;
    
    struct P{
        int l,r;
    }d[1001];
    
    int n,ans=0x3f3f3f3f,a[1001],pre[1001];
    bool vis[1001];
    
    void dfs(int x)
    {
        if(x>n) 
        {
            int t=0;
            for(int i=1;i<=n;++i) 
                t=max(pre[i-1]/d[a[i]].r,t);
            ans=min(ans,t);
            return ;
        }
        for(int i=1;i<=n;++i) 
        {
            if(vis[i]) continue;
            vis[i]=1;
            a[x]=i;
            pre[i]=pre[i-1]*d[i].l;
            dfs(x+1);
            vis[i]=0;
        }
    }
    
    int main()
    {
    //    freopen("game.in","r",stdin),freopen("game.out","w",stdout);
        scanf("%d",&n);
        for(int i=0;i<=n;++i)
            scanf("%d%d",&d[i].l,&d[i].r);
        memset(pre,0,sizeof(pre));
        pre[0]=d[0].l;
        dfs(1);
        printf("%d",ans);
        return 0;
    }

    60分的无高精度

    #include<stdio.h>
    #include<algorithm> 
    using namespace std;
    int n;
    long long t,pre,ans;
    
    struct node {
        int l,r,f;
    }a[1001];
    
    bool cmp(node a,node b){
        return a.f<b.f;
    }
    
    int main()
    {
        scanf("%d",&n);
        scanf("%d%lld",&pre,&t); 
        for(int i=1;i<=n;++i) 
        {
            scanf("%d%d",&a[i].l,&a[i].r);
            a[i].f=a[i].l*a[i].r;
        }
        sort(a+1,a+1+n,cmp);
        
        for(int i=1;i<=n;++i) 
        {
            t=(long long)pre/a[i].r;
            if(t)
                ans=max(ans,t);
            pre*=a[i].l;
        }
        printf("%lld",ans);
        return 0;
    }

    AC高精度

    #include <cstdio>
    #include <string>
    #include <cstdlib>
    #include <cmath>
    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    struct node {
        int l,r,f;
    }a[1001];
    
    bool cmp(node a,node b){
        return a.f<b.f;
    }
    
    struct BigInt {
        vector<int> v;
        static const int BASE = 10000;
        static const int WIDTH = 4;
        BigInt(long long x) {
            do {
                v.push_back(x % BASE);
            }while (x /= BASE);
        }
        BigInt(string str) {
            int size = str.length();
            v.reserve(size);
            for(int i = size - 1; i >= 0; i-=WIDTH){
                string sub;
                if(i-WIDTH + 1<0)sub = str.substr(0,i+1);
                else sub = str.substr(i - WIDTH +1,WIDTH);
                int temp = atoi(sub.c_str());
                v.push_back(temp);
            }
        }
        BigInt() {
            
        }
        void removePreZero() {
            while(v.size() >= 1 && v.back() == 0) v.pop_back();
        }
        bool operator<(const BigInt &a) const {
            if (v.size() != a.v.size()) {
                return v.size() < a.v.size();
            }
            for (int i = v.size() - 1; i >= 0; i--) {
                if (v[i] != a.v[i]) {
                    return v[i] < a.v[i];
                }
            }
            return false;
        }
        bool operator>(const BigInt &a) const {return a < *this;}
        bool operator<=(const BigInt &a) const {return !(a < *this);}
        bool operator>=(const BigInt &a) const {return !(*this < a);}
        bool operator!=(const BigInt &a) const {return a < *this || a > *this;}
        bool operator==(const BigInt &a) const {return !(a < *this) && !(a > *this);}
        BigInt operator+(const BigInt &a) const {
            BigInt ans;
            ans.v.reserve(max(a.v.size(), v.size()));
            int sum = 0;
            for (int i = 0; i < max(a.v.size(), v.size()); i++) {
                if (i < a.v.size()) sum += a.v[i];
                if (i < v.size()) sum += v[i];
                ans.v.push_back(sum % BASE);
                sum /= BASE;
            }
            if (sum) ans.v.push_back(sum);
            ans.removePreZero();
            return ans;
        }
    /*    BigInt operator+=(const BigInt &a) const {
            return *this = *this + a;
        }*/
        BigInt operator-(const BigInt &a) const {
            BigInt ans;
            ans.v.reserve(max(a.v.size(), v.size()));
            int dif = 0;
            for (int i = 0; i < max(a.v.size(), v.size()); i++) {
                if (i < v.size()) dif += v[i];
                if (i < a.v.size()) dif -= a.v[i];
                if (dif >= 0) {
                    ans.v.push_back(dif);
                    dif = 0;
                } else {
                    ans.v.push_back((dif +BASE) % BASE);
                    dif = -1;
                }
            }
            ans.removePreZero();
            return ans;
        }
    /*    BigInt operator-=(const BigInt &a) const {
            return *this = *this - a;
        }*/
        BigInt operator*(const BigInt &a) const {
            BigInt ans;
            ans.v.resize(v.size() + a.v.size(), 0);
            for (int i = 0; i < v.size(); i++) {
                for (int j = 0; j < a.v.size(); j++) {
                    ans.v[i + j] += v[i] * a.v[j];
                    ans.v[i + j + 1] += ans.v[i + j] / BASE;
                    ans.v[i + j] %= BASE;
                }
            }
            ans.removePreZero();
            return ans;
        }
    /*    BigInt operator*=(const BigInt &a) const {
            return *this = *this * a;
        }*/ 
        BigInt operator/(const BigInt &a) const {
            BigInt ans, ret(0);
            ans.v.resize(v.size(), 0);
        //    ret = 0;
            for (int i = v.size() - 1; i >= 0; i--) {
                ret = ret * BASE + v[i];
                while (ret >= a) {
                    ret = ret - a;
                    ans.v[i]++;
                }
            }
            ans.removePreZero();
            return ans;
        }
        BigInt operator/(const int &a) const {
            BigInt ans;
            ans.v.resize(v.size(), 0);
            int    ret = 0;
            for (int i = v.size() - 1; i >= 0; i--) {
                ret += v[i];
                if(ret >= a){
                    ans.v[i] += ret/a;
                    ret%=a;
                }
                ret*=BASE;
            }
            ans.removePreZero();
            return ans;
        }
        
        void print(){
            if(v.size()==0)printf("0");
            for(int i = v.size() - 1 ; i >= 0 ; i--){
                if(i!=v.size()-1){
                    if(v[i]<10)printf("000");
                    else if(v[i]<100)printf("00");
                    else if(v[i]<1000)printf("0");
                }
                printf("%d",v[i]);
            }
        
        }
    /*    BigInt operator/=(const BigInt &a) const {
            return *this = *this / a;
        }*/
    }ans,pre,t;
    int n,temp,t1,t2;
    
    int main()
    {
        scanf("%d",&n);
        scanf("%d%d",&t1,&t2);
        pre=t1;
        for(int i=1;i<=n;++i) 
        {
            scanf("%d%d",&a[i].l,&a[i].r);
            a[i].f=a[i].l*a[i].r;
        }
        sort(a+1,a+1+n,cmp);
        
        for(int i=1;i<=n;++i) 
        {
            t=pre/a[i].r;
            if(t>ans)
                ans=t;
            pre=pre*a[i].l;
        }
        ans.print();
        return 0;
    } 
    从0到1很难,但从1到100很容易
  • 相关阅读:
    Action返回类型
    低成本FPGA中实现动态相位调整
    SERDES高速系统(二)
    SERDES高速系统(一)
    Avalon总线概述
    FPGA热设计
    功耗的挑战
    特性阻抗介绍
    低阻抗电源分配系统
    非理想回路信号衰减
  • 原文地址:https://www.cnblogs.com/qseer/p/9605324.html
Copyright © 2011-2022 走看看