洛谷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]}

若交换

则,ans2 = max{S / B[i + 1], S * A[i + 1] / B[i]}

因为,A[i] B[i] <= A[i + 1] B[i + 1]

所以,S A[i] / B[i + 1] <= S A[i + 1] / B[i]

又因为,S / B[i + 1] <= S * A[i] / B[i + 1]

所以,ans2 = S * A[i + 1] / B[i]

ans1 = max{S / B[i], S * A[i] / B[i + 1]}

所以,ans1 <= ans2

证毕 至于高精度:

由题意知,0 < a,b < 10000,所以用10000进制的高精度进行运算就可以了

转自 新浪博客

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<ctime>
  6 #include<iostream>
  7 #include<algorithm>
  8 using namespace std;
  9 int N;
 10 int a[1005],b[1005],ka,kb;
 11 int ans[20000],t[20000],lena,lent,tt[20000],t2[20000],len;
 12 void _qst_ab(int l,int r)
 13 {
 14     int i=l,j=r,ma=a[(i+j)>>1],mb=b[(i+j)>>1];
 15     while(i<=j)
 16     {
 17         while(a[i]*b[i]<ma*mb) i++;
 18         while(a[j]*b[j]>ma*mb) j--;
 19         if(i<=j)
 20         {
 21             swap(a[i],a[j]);
 22             swap(b[i],b[j]);
 23             i++;j--;
 24         }
 25     }
 26     if(l<j) _qst_ab(l,j);
 27     if(i<r) _qst_ab(i,r);
 28 }
 29 void _init()
 30 {
 31     scanf("%d%d%d",&N,&a[0],&b[0]);
 32     for(int i=1;i<=N;i++)
 33         scanf("%d%d",&a[i],&b[i]);
 34 }
 35 void _get_t(int Left,int Right)
 36 {
 37     for(int i=1;i<=lent;i++)
 38     {
 39         tt[i]+=t[i]*Left;
 40         tt[i+1]+=tt[i]/10;
 41         tt[i]%=10;
 42     }
 43     lent++;
 44     while(tt[lent]>=10)
 45     {
 46         tt[lent+1]=tt[lent]/10;
 47         tt[lent]%=10;
 48         lent++;
 49     }
 50     while(lent>1&&tt[lent]==0) lent--;
 51     len=lent;
 52     memcpy(t,tt,sizeof(tt));
 53     memset(tt,0,sizeof(tt));
 54     for(int i=1,j=len;i<=len;i++,j--)
 55         t2[i]=t[j];
 56     int x=0,y=0;
 57     for(int i=1;i<=len;i++)
 58     {
 59         y=x*10+t2[i];
 60         tt[i]=y/Right;
 61         x=y%Right;
 62     }
 63     x=1;
 64     while(x<len&&tt[x]==0) x++;
 65     memset(t2,0,sizeof(t2));
 66     for(int i=1,j=x;j<=len;i++,j++)
 67         t2[i]=tt[j];
 68     memcpy(tt,t2,sizeof(t2));
 69     len=len+1-x;
 70 }
 71 bool _cmp()
 72 {
 73     if(len>lena) return true;
 74     if(len<lena) return false;
 75     for(int i=1;i<=len;i++)
 76     {
 77         if(ans[i]<tt[i]) return true;
 78         if(ans[i]>tt[i]) return false;
 79     }
 80     return false;
 81 }
 82 void _solve()
 83 {
 84     _qst_ab(1,N);
 85     t[1]=1;lent=1;
 86     for(int i=1;i<=N;i++)
 87     {
 88         memset(tt,0,sizeof(tt));
 89         len=0;
 90         _get_t(a[i-1],b[i]);
 91         if(_cmp())
 92         {
 93             memcpy(ans,tt,sizeof(tt));
 94             lena=len;
 95         }
 96     }
 97     for(int i=1;i<=lena;i++)
 98         printf("%d",ans[i]);
 99     printf("\n");
100 }
101 int main()
102 {
103     _init();
104     _solve();
105     return 0;
106 }  
时间: 2024-08-02 06:58:14

洛谷P1080 国王游戏 高精度 贪心 数学推公式的相关文章

[NOIP2012] 提高组 洛谷P1080 国王游戏

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

洛谷 P1080 国王游戏

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

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

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

洛谷P1199 三国游戏 博弈论 数学

洛谷P1199 三国游戏博弈论 数学 这道题 其实 人是必胜的 能取到的最大值 为 每行第二大值中的最大值 为什么呢 假使第一次我们取到了我们心中的那个答案的所在行 那么接着电脑会取 这一行最大值的对应行 那么我们来分析一下电脑取的那个数在他取的那行的特点 首先我们假设其不是最大值,因为矩阵中任意两个数不相同 所以也就是说还有个数比他大,然后就是说电脑取的第二大或者第n大值就已经比我们取的第一大值要大了,说明我们取的行并不是每行第二大值中的最大值所在的行2.也就是说这个数必定为该行中的最大值 那

洛谷P1061 Jam的计数法 数学

洛谷P1061 Jam的计数法 数学 已知一个字符串 其 均有 s--t构成 且字符串要求 s[ i ]<s[ j ] i < j 已知一个字符串 求按字典序排列 的后5个字符串 1. 对于一个字符串已知,我们如何求他的下一个字符串呢? 我们可以从低位枚举到高位,找到第一个可以增长的数,然后增长2.同时把自己后面的串改为字典序最小,即这一位为上一位 + 1 这样字典序就最小了 1 #include <cstdio> 2 #include <cmath> 3 #inclu

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

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

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[

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

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

【不可能的任务24/200】洛谷1640 bzoj1854游戏 匈牙利就是又短又快

bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个“大牛分站”,就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类似于匈牙利(⊙o⊙) (匈牙利的复杂度惊人,1e6秒过) 1 #include <cstdio> 2 bool b[3000001]; 3 int c[3000001],fir[3000001],to[3000001],nex[3000001]; 4 int N,n,p,q; 5 void add(int p,int