• luogu P1080 国王游戏


    题目描述

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

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

    输入输出格式

    输入格式:

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

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

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

    输出格式:

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

    输入输出样例

    输入样例#1:
    3 
    1 1 
    2 3 
    7 4 
    4 6 
    输出样例#1:
    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%的数据,保证答案不超过 10^9;

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

    NOIP 2012 提高组 第一天 第二题

    首先相邻两个交换影响的答案只有它们两个

    所以考虑让所有相邻的最优 假设 i,j (i+1=j),a[k]*a[1]*...*a[i-1]=S

    则不交换顺序 与 交换顺序的答案(Max)分别为

    max{S/b[i], S*a[i]/b[i]} -> max{1/b[i] , a[i]/b[j]} -> max{b[j]/b[i]b[j] , a[i]b[i]/b[i]b[j]}

    max{S/b[j], S*a[j]/b[i]} -> max{1/b[j] , a[j]/b[i]} -> max{b[i]/b[i]b[j] , a[j]b[j]/b[i]b[j]} 两式比较

    同去分母得 max{b[j] , a[i]b[i]} ? max{b[i] , a[j]b[j]}

    设 a[i]*b[i] > a[j]*b[j]

    显然 a[i]b[i] > b[j], a[j]b[j] > b[i] 则

    两式比较 = a[i]*b[i] > a[j]*b[j]

    所以 a[i]*b[i] > a[j]*b[j] 时,

    不交换i,j会使答案更大

    #include<cstdio> 
    #include<cstring>
    #include<iostream>
    #include<algorithm> 
    using namespace std;
    int n,sum[10000],t[10000],ans[10000];
    struct node{
        int l,r,s;
        bool operator < (const node &a) const {
            return s<a.s;
        }
    }peo[1003];
    bool judge() {
        for(int i=1;i<=t[0];++i) 
            if(t[i]>ans[i]) return true;
            else if(t[i]<ans[i])return false;
        return false;
    }
    void mul(int x) {
        int g=0;
        for(int i=1;i<=sum[0];++i) {
            sum[i]=sum[i]*x+g;
            g=sum[i]/10;
            sum[i]=sum[i]%10;
        }
        while(g!=0) {
            ++sum[0];
            sum[sum[0]]=g%10;
            g/=10;
        }
    }
    void divv(int x) {
        int num=0;int k=sum[0]+1,s=0;
        memset(t,0,sizeof(t));
        while(num<x) {
            --k;
            num=num*10+sum[k];
        }
        t[0]=k;
        for(;k>=1;--k) {
            t[++s]=num/x;
            num=num%x*10+sum[k-1];
        }
        if(t[0]>ans[0]||t[0]==ans[0]&&judge()) {
            ans[0]=t[0];
            for (int i=1;i<=t[0];++i) ans[i]=t[i];
        }
        
    }
     int main () {
        scanf("%d",&n);int a,b;
        scanf("%d%d",&a,&b);
        sum[1]=a;sum[0]=1;ans[0]=1;ans[1]=0;
        for(int i=1;i<=n;++i) {
            scanf("%d%d",&peo[i].l,&peo[i].r);
            peo[i].s=peo[i].l*peo[i].r;
        }
        sort(peo+1,peo+n+1);
        for(int i=1;i<=n;++i) {
            mul(peo[i].l);
            divv(peo[i].l*peo[i].r);
        }
        for(int i=1;i<=ans[0];++i) printf("%d",ans[i]);
        puts("");
        return 0;
    }
  • 相关阅读:
    sqlserver建立临时表
    动态引用WebService
    技术的力量:30分钟的动画片和《彗星撞地球》超炫的动画 仅64K
    sqlserver2005新功能函数
    使用面向对象的、完整的单点登录功能
    asp.net上传功能(单文件,多文件,自定义生成缩略图,水印)
    C#对字符和文件的加密解密类
    JavaScript中setInterval函数应用常见问题之一(第一个参数不加引号与加引号的区别)
    JavaScript表格隔行换色悬停高亮
    Javascript模拟c#中arraylist操作(学习分享)
  • 原文地址:https://www.cnblogs.com/sssy/p/7701829.html
Copyright © 2020-2023  润新知