zoukankan      html  css  js  c++  java
  • P1080 国王游戏 贪心 高精度

      

    题目描述

    恰逢 HH国国庆,国王邀请nn 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 nn 位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。

    国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。

    输入输出格式

    输入格式:

    第一行包含一个整数nn,表示大臣的人数。

    第二行包含两个整数 aa和 bb,之间用一个空格隔开,分别表示国王左手和右手上的整数。

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

    输出格式:

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

    输入输出样例

    输入样例#1: 复制
    3 
    1 1 
    2 3 
    7 4 
    4 6 
    输出样例#1: 复制
    2

    说明

    【输入输出样例说明】

    11、22、33 这样排列队伍,获得奖赏最多的大臣所获得金币数为 22;

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

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

    22、33、11这样排列队伍,获得奖赏最多的大臣所获得金币数为99;

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

    33、22、11 这样排列队伍,获得奖赏最多的大臣所获得金币数为 99。

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

    【数据范围】

    对于 20%的数据,有 1≤ n≤ 10,0 < a,b < 81n10,0<a,b<8;

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

    对于 60%的数据,有 1≤ n≤1001n100;

    对于 60%的数据,保证答案不超过 10^9109;

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

    NOIP 2012 提高组 第一天 第二题

    右边的数是除数  按照右边为第一优先级  左边为第二优先级  都降序排序   比较符合贪心原则  但是只能过6个点

    #include<bits/stdc++.h>
    using namespace std;
    //input
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);i--)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m);
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define inf 0x3f3f3f3f
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define N 1000+5
    struct node
    {
        int l,r;
    }s[N];
    bool cmp(node a,node b)
    {
        return a.l<b.l||a.l==b.l&&a.r<b.r;
    }
    bool cmp2(node a,node b)
    {
        return a.r<b.r||a.r==b.r&&a.l<b.l;
    }
    int main()
    {
        int n;
        int L,R;
        RIII(n,L,R);
        rep(i,1,n)
        RII(s[i].l,s[i].r);
    
        sort(s+1,s+1+n,cmp2);
        ll maxx2=-99000999999;
        ll sum=L;
        rep(i,1,n)
        {
            maxx2=max(maxx2,sum/s[i].r);
            sum*=s[i].l;
        }
        cout<<maxx2;
    
        return 0;
    }
    View Code

    剩下的点为高精度 

    事实证明上面的贪心原则是错误的  只是我想当然而已

    参考了大佬的题解:

     

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <string>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    int n, lens = 1, lenm = 1, lena = 1;
    int sum[10010] = {0, 1}, maxn[10010] = {0, 1}, ans[10010];
    
    struct tmp
    {
        long long l, r;
        bool operator < (const tmp x) const 
        {
                return l * r < x.l * x.r;
        }
    }coin[1001];
    
    void muti(long long x)
    {
        int tmp = 0;
        for(int i = 1; i <= lens; i++)
            sum[i] *= x;
        for(int i = 1; i <= lens; i++)
        {
            tmp += sum[i];
            sum[i] = tmp %10;
            tmp /= 10;
        }
        while(tmp != 0)
        {
            lens++;
            sum[lens] = tmp % 10;
            tmp /= 10;
        }
    }
    
    void cut(long long x)
    {
        memset(ans, 0, sizeof(ans));
        lena = lens;
        int tmp = 0;
        for(int i = lena; i >= 1; i--)
        {
            tmp *= 10;
            tmp += sum[i];
            if(tmp >= x)
            {
                ans[i] = tmp / x;
                tmp %= x;
            }
        }
        while(ans[lena] == 0)
        {
            if(lena == 1)
                break;
            lena--;
        }
    }
    
    void max()
    {
        if(lena > lenm)
        {
            for(int i = 1; i <= lena; i++)
                maxn[i] = ans[i];
            lenm = lena;
        }
        else if(lena == lenm)
        {
            for(int i = lena; i >= 1; i--)
                if(maxn[i] < ans[i])
                {
                    for(int j = 1; j <= lena; j++)
                        maxn[j] = ans[j];
                    lenm = lena;
                    break;
                }
        }
    }
    
    int main()
    {
    //  freopen("game.in", "r", stdin);
    //  freopen("game.out", "w", stdout);
        cin >> n;
        cin >> coin[0].l >> coin[0].r;
        for(int i = 1; i <= n; i++)
            scanf("%d %d", &coin[i].l, & coin[i].r);
        sort(coin + 1, coin + n + 1);
        for(int i = 1; i <= n; i++)
        {
            muti(coin[i - 1].l);
            cut(coin[i].r);
            max();
        }
        for(int i = lenm; i >= 1; i--)
            cout << maxn[i];
    }
    View Code
  • 相关阅读:
    【理财启蒙】理财:需要树立正确的金钱观
    【系统设计】分布式唯一ID生成方案总结
    【Hash一致性算法】什么是Hash一致性算法
    【位图算法】什么是BitMap
    关于枚举类你可能不知道的事
    【数据结构】什么是AVL树
    mysql5.6 主从同步配置
    vmstat命令详解
    pstack跟踪进程栈
    iostat 磁盘io分析工具
  • 原文地址:https://www.cnblogs.com/bxd123/p/10661842.html
Copyright © 2011-2022 走看看