luogu P1080 国王游戏
题目描述
恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 n 位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。
国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。
输入输出格式
输入格式:
第一行包含一个整数 n,表示大臣的人数。
第二行包含两个整数 a和 b,之间用一个空格隔开,分别表示国王左手和右手上的整数。
接下来 n 行,每行包含两个整数 a 和 b,之间用一个空格隔开,分别表示每个大臣左手和右手上的整数。
输出格式:
输出只有一行,包含一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的金币数。
输入输出样例
3 1 1 2 3 7 4 4 6
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; }