【贪心+排序】国王游戏

【贪心+排序】国王游戏

Time Limit: 1000MS
Memory Limit: 131072KB

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

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

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

Sample Input
3
1 1
2 3
7 4
4 6

Sample Output
2

Hint
【输入输出样例说明】按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。

Source
noip2012

这题数据很水

暴搜20分

我没想到以左右手的成绩为关键字排序

真弱真悲伤

我以左手为关键字排序错误贪心加上暴搜得了30分

正解:

我们先考虑只有两个人的情况

第一个人:l/r1  
l*l1/r2;很明显l*l1/r2>l/r1;

第二个人:l/r2  
l*l2/r1;  很明显l*l2/r1>l/r2;

比较max(l1/r2,l2/r1)=(l1*r1,l2*r2);

所以可以用贪心以左右手的乘积为顺序然后依次枚举

TOT 我高精度又TM写丑了

竟然三个点超时

但是数据很水

只要枚举最后一个人与第一个人

还是没理解透彻

能证明枚举最后一个人与第一个人是对的额

所以领袖说的很对 noip的题数据很水

所以我还是先练练高精度吧

# include<stdio.h>
# include<cstring>
# include<iostream>
# include<vector>
# include<algorithm>
using namespace std;
const int maxn=10000;
typedef long long LL;
char tb[maxn];
struct node{
    LL  l;
    LL  r;
}edge[1000+10];
LL  gl,gr,n,Min=-0x7fffffff,MIN=0x7fffffff;
LL  vis[maxn],a[maxn],c[maxn],str[maxn];
LL  cmp(const node &A,const node &B){
    return A.l*A.r<B.l*B.r;
}
void check(){
    if(a[0]<str[0])return;
    else if(a[0]>str[0]){str[0]=a[0];for(int i=1;i<=a[0];i++)str[i]=c[i];}
    else if(a[0]==str[0])
    for(int i=a[0];i>=1;i--)
    if(c[i]>str[i]){
    for(int i=1;i<=a[0];i++)str[i]=c[i];
    break;
    }
}
void mul(LL x){
  LL i,m=0;
  for (i=1;i<=a[0];i++){
    m=m+a[i]*x;
    a[i]=m%10;
    m=m/10;
  }
  while(m!=0){
    a[0]++;
    a[a[0]]=m%10;
    m=m/10;
  }
}
void di(int b){
    LL  x=0;
    for(LL i=a[0];i>=1;i--){
        c[i]=(x*10+a[i])/b;
        x=(x*10+a[i])%b;
    }
    while(c[a[0]]==0&&a[0]!=1)a[0]--;
}
void init(){
    cin>>n;
    cin>>gl>>gr;
    for(LL  i=1;i<=n;i++)
    scanf("%I64d%I64d",&edge[i].l,&edge[i].r);
}
void yy(){
    LL x1=-0x7fffffff,x2=-0x7fffffff;
    sort(edge+1,edge+n+1,cmp);
    for(LL  i=n;i<=n;i++){
        memset(a,0,sizeof(a));
        memset(c,0,sizeof(c));
        LL cur=0;
        LL t=gl;
        while(t!=0){a[++cur]=t%10;t=t/10;}
        a[0]=cur;
        for(LL  j=1;j<i;j++)
        mul(edge[j].l);
        di(edge[i].r);
        check();
    }
        for(LL  i=1;i<=1;i++){
        memset(a,0,sizeof(a));
        memset(c,0,sizeof(c));
        LL cur=0;
        LL t=gl;
        while(t!=0){a[++cur]=t%10;t=t/10;}
        a[0]=cur;
        for(LL  j=1;j<i;j++)
        mul(edge[j].l);
        di(edge[i].r);
        check();
    }
    for(int i=str[0];i>=1;i--)
    cout<<str[i];
}
void dfs(LL  cur,LL  much){
    if(cur==n){
        LL  k;
        for(LL  i=1;i<=n;i++)
        if(!vis[i]){k=i;break;}
        MIN=min(MIN,much/edge[k].r);
        return;
    }
    for(LL  i=1;i<=n;i++)
    if(!vis[i]){
        vis[i]=1;
        dfs(cur+1,much*edge[i].l);
        vis[i]=0;
    }
}
void easy(){
    dfs(1,gl);
    cout<<MIN;
}
int  main(){
    init();
    //easy();
     yy();
    return 0;
}
时间: 2024-08-03 07:00:55

【贪心+排序】国王游戏的相关文章

洛谷P1080 国王游戏 高精度 贪心 数学推公式

洛谷P1080 国王游戏        数学推公式      高精度    贪心 然而这并不是我打出来的,抄题解... 将左手与右手的乘积从小到大排序,然后计算求最大值即可.(需要高精度) 证明: 1)知道,如果相邻的两个人交换位置,只会影响到这两个人的值,不会影响他人 2)假设相邻的两个人i, i + 1.设A[i] B[i] <= A[i + 1] B[i + 1],i之前所有人的左手乘积为S. 则,ans1 = max{S / B[i], S * A[i] / B[i + 1]} 若交换

# 国王游戏(贪心+大数乘除+微扰法证明)

国王游戏(贪心+大数乘除+微扰法证明) 题意:n个大臣和一个国王,左右手都有一个数,排队,国王始终拍在最前面,每个大臣的奖励为这个大臣前面的人的左手上的数之积除以这个大臣右手上的数.构造最优队伍,使得奖励最多的大臣的奖励最少. 证明: 微扰法的使用 我们现在将任意两个人的位置互换,然后考虑他们在交换前和交换后所获得的奖励是多少,其他人的奖励不变: 交换前: 第 \(i\) 个人是 : \(A_0 * A_1*....*A_{i-1}/B_i\) 第 \(i+1\) 个人是 : \(A_0 * A

【NOIP 2012 国王游戏】 贪心+高精度

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

国王游戏(贪心+大数)

                                                   4824: 国王游戏 时间限制(普通/Java):3000MS/9000MS     内存限制:65536KByte总提交: 2            测试通过:1 描述 恰逢H国国庆,国王邀请n位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这n位大臣排成一排,国王站在队伍的最前面.排好队后,所有的大臣都会获得国王奖赏的若干

luoguP1080 国王游戏 题解(NOIP2012)(贪心+高精)

luoguP1080 国王游戏 题目 #include<iostream> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define il inline #define rg register #define ll long long #define N 10001 #define inf 10000

洛谷P1080 [NOIP2012提高组D1T2]国王游戏 [2017年5月计划 清北学堂51精英班Day1]

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

noip2012 国王游戏

1198 国王游戏 2012年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n位大臣排成一排,国王站在队伍的最前面.排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手

AC日记——国王游戏 洛谷 P1080

国王游戏 思路: 贪心+高精: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1005 struct DataType { int a,b,key; bool operator<(const DataType pos)const { return key<pos.key; } }; struct DataType ai[maxn]; struct BintType { int len; char ch[

2012年 国王游戏

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