NOIP2012 国王游戏

传送门

贪心还是很舒服的,不过加上高精度就很难受……

我们要求的是得到金钱最多的大臣得到的钱数尽可能少。看到这个问题可能会想起二分答案之类的……不过看看这数据范围就知道不可能。想起之前做过一道类似的题,考虑一下贪心。

直接贪心肯定是看不出来啥,那我们还是老套路,交换一下两个大臣。假设前面所有人乘积为w,第一个大臣左右手上的数为l1,r1,第二个为l2,r2.那么第一个大臣得到的钱就是w / r1,第二个是w * l1 / r2.交换之后,第一个大臣得到的是w / r2,第二个大臣得到的是w * l2 / r1,很显然我们只要比较w * l1 / r2和w * l2 / r1的大小即可。进行移项之后,发现w * l1 / r2 > w * l2 / r1的条件是l1 * r1 > l2 * r2.不过我们为了尽量让多的更少,所以我们肯定要逆着它来,把l,r乘积较大的大臣放在后面即可。

之后就要上高精度了……好久没写高精度,这次补上了一发自己的高精度模板吧……只需要高精乘和高精除低精还是可以的。用重载运算符写题真爽

看一下代码。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('
')
#define pr pair<int,int>
#define mp make_pair
#define fi first
#define sc second
using namespace std;
typedef long long ll;
const int M = 5005;
const int N = 10000005;
 
ll read()
{
   ll ans = 0,op = 1;
   char ch = getchar();
   while(ch < '0' || ch > '9')
   {
      if(ch == '-') op = -1;
      ch = getchar();
   }
   while(ch >='0' && ch <= '9')
   {
      ans *= 10;
      ans += ch - '0';
      ch = getchar();
   }
   return ans * op;
}

struct dc
{
   ll l,r;
   bool operator < (const dc &g) const
   {
      return l * r < g.l * g.r;
   }
}c[M];

struct big
{
   int f[M],len;
   big()
   {
      memset(f,0,sizeof(f)),len = 0;
   }
   big change(int k)
   {
      big a;
      while(k) a.f[a.len++] = k % 10,k /= 10;
      while(!a.f[a.len] && a.len > 0) a.len--;
      return a;
   }
   void modi(int k)
   {
      while(k) f[len++] = k % 10,k /= 10;
      while(!f[len] && len > 0) len--;
   }
   big operator * (const big &g) const
   {
      big c;
      c.len = len + g.len + 1;
      //printf("!%d %d %d
",len,g.len,c.len);
      rep(i,0,len)
      rep(j,0,g.len)
      c.f[i+j] += f[i] * g.f[j];
      rep(i,0,c.len-1) c.f[i+1] += c.f[i] / 10,c.f[i] %= 10;
      while(!c.f[c.len] && c.len > 0) c.len--;
      return c;
   }
   big operator / (const int &g)
   {
      big c;
      int cur = 0;
      per(i,len,0) cur *= 10,cur += f[i],c.f[c.len++] = cur / g,cur %= g;
      reverse(c.f,c.f + c.len);
      while(!c.f[c.len] && c.len > 0) c.len--;
      return c;
   }
   void print()
   {
      per(i,len,0) printf("%d",f[i]);enter;
   }
}kl,kr,ans;

ll ka,kb,n;

big bmax(const big &a,const big &b)
{
   if(a.len != b.len) return a.len > b.len ? a : b;
   per(i,a.len,0)
   {
      if(a.f[i] == b.f[i]) continue;
      else return a.f[i] > b.f[i] ? a : b;
   }
   return a;
}

int main()
{
   n = read();
   ka = read(),kb = read();
   kl.modi(ka),kr.modi(kb);
   //kl.print(),kr.print();
   rep(i,1,n) c[i].l = read(),c[i].r = read();
   sort(c+1,c+1+n);
   rep(i,1,n)
   {
      big L,R;
      L.modi(c[i].l);
      //L.print();putchar('#');
      big cur = kl / c[i].r;
      ans = bmax(ans,cur);
      kl = kl * L;
      //kl.print();
   }
   ans.print();
   return 0;
}
原文地址:https://www.cnblogs.com/captain1/p/9873487.html