[NOIP2012] 国王游戏

题意:有一个国王和n个大臣,排成一列玩一个,每个人左右手分别有一个数值,每个人的分值定义为之前所有人左手的分值和除以自己右手的分值(下取整),国王始终站在最前面,现要你安排大臣的顺序,使得分值最大的大臣的分值尽量小

题解:

贪心+高精

按左右手乘积从小到大排序

所有数的乘积最大不超过(10^{4000}),码一发高精乘低精和高精除低精即可

注意:比较s和g时写成函数会wa,可能传指针的时候会有鬼畜的事情发生= =、

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 5000
using namespace std;

int g[N],f[N],s[N];

struct Node {
    int a,b;
    bool operator < (const Node &x) const {
        return a*b<x.a*x.b;
    }
}p[1010];

int gi() {
  int x=0,o=1; char ch=getchar();
  while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
  if(ch=='-') o=-1;
  while(ch>='0' && ch<='9') x=10*x+ch-'0',ch=getchar();
  return x*o;
}

void work(int u) {
  int a=p[u].a,b=p[u].b,x=0,flg=0;
    memset(s,0,sizeof(s));
    for(int i=f[0]; i>=1; i--) {
        x=10*x+f[i];
        if(x/b) {
	  s[i]=x/b,x-=b*(x/b);
	  if(!flg) flg=1,s[0]=i;
	}
    }
    if(g[0]<s[0]) memcpy(g,s,sizeof(s));
    else if(g[0]==s[0]) {
      for(int i=g[0]; i>=1; i--) {
	if(g[i]<s[i]) {memcpy(g,s,sizeof(s));break;}
	if(g[i]>s[i]) break;
      }
    }
    x=0;
    for(int i=1; i<=f[0]; i++) {
        f[i]=f[i]*a+x;
        x=f[i]/10,f[i]%=10;
    }
    while(x) f[++f[0]]=x%10,x/=10;
}

int main() {
    int n=gi(),x=gi(),y=gi();
    for(int i=1; i<=n; i++) {
        p[i].a=gi(),p[i].b=gi();
    }
    sort(p+1,p+n+1);
    while(x) f[++f[0]]=x%10,x/=10;
    for(int i=1; i<=n; i++) work(i);
    if(!g[0]) printf("0");
    else 
      for(int i=g[0]; i>=1; i--) {
        printf("%d", g[i]);
      }
    return 0;
} 

原文地址:https://www.cnblogs.com/HLXZZ/p/7630565.html