zoukankan      html  css  js  c++  java
  • [NOIP2012]国王游戏 -高精度-贪心-

    描述

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

    Solution

    贪心。左手的数用(l[i])表示,右手的数用(r[i])表示,只需以(l[i] * r[i])为关键字从小到大排序,求出奖赏最多的大臣所获的奖赏即可。

    但是为什么呢?

    可以考虑相邻的两个大臣(a_i和a_{i+1}),他们的奖赏分别为(左边为(a_i),右边为(a_{i+1}))

    (frac{1}{r[i]}*prodlimits_{k=0}^{i-1}l[k]和frac{1}{r[i+1]}*prodlimits_{k=0}^{i}l[k])

    交换位置后他们的奖赏为

    (frac{l[i + 1]}{r[i]}*prodlimits_{k=0}^{i-1}l[k]和frac{1}{r[i+1]}*prodlimits_{k=0}^{i-1}l[k])

    然后我们来比较

    (max(frac{1}{r[i+1]}*prodlimits_{k=0}^{i-1}l[k],frac{l[i]}{r[i]}*prodlimits_{k=0}^{i-1}l[k])和max(frac{1}{r[i]}*prodlimits_{k=0}^{i-1}l[k],frac{1}{r[i+1]}*prodlimits_{k=0}^{i}l[k]))

    同乘(frac{1}{r[i+1]*r[i]}*prodlimits_{k=0}^{i-1}l[k])

    即比较
    (\max(r[i + 1],l[i]*r[i])................1\max(r[i],r[i+1]*l[i+1])...............2)
    (\r[i+1] < r[i + 1]*l[i + 1]且r[i] < r[i] * l[i])

    (l[i]*r[i] < l[i+1]*r[i+1])时,(1)式小于(2)式,交换前更优,即把(l[i]*r[i])小的放在前面更优。

    #include<bits/stdc++.h>
    using namespace std;
    const int MOD = 10000;
    struct bint{
      int a[5000], len;
      int& operator [] (int x) { return a[x]; }
      bint():len(1){ memset(a, 0, sizeof(a));}
      bint(long long x) { memset(a, 0, sizeof(a)); len = 0; while(x) { a[++len] = x % MOD; x /= MOD; } }
      void print(){
        printf("%d", a[len]);
        for (int i = len - 1; i > 0; i--)
          printf("%04d", a[i]);
      }
    };
    bint operator * (bint& a,int b){
      int x = 0;
      for (int i = 1; i <= a.len; i++) 
        x += a[i] * b, a[i] = x % MOD, x /= MOD;
      if(x) a[++a.len] = x;
      return a;
    }
    bint operator / (bint& a,int b){
      bint c; c.len = a.len; int x = 0;
      for (int i = a.len; i > 0; i--) {
        x = x * MOD + a[i];
        c[i] = x / b;
        x %= b;
      }
      while(c[c.len] == 0 && c.len > 1) c.len--;
      return c;
    }
    bool operator < (bint& a,bint & b){
      if(a.len > b.len) return false;
      if(a.len < b.len) return true;
      for(int i = a.len; i >= 0; i--){
    		if(a[i] < b[i]) return true;
    		if(a[i] > b[i]) return false;
    	}
    	return false;
    }
    struct obj{
      int l, r, lr;
    }a[1010];
    bool cmp(obj a,obj b){
      return a.lr < b.lr;
    }
    int n;
    int main(){
      cin >> n;
      for (int i = 0; i <= n; i++){
        cin >> a[i].l >> a[i].r;
        a[i].lr = a[i].l * a[i].r;
      }
      sort(a + 1, a + n + 1, cmp);
      bint s(1),ans;
      
      for (int i = 1; i <= n; i++){
        if(a[i - 1].l == 0) break;
        s = s * a[i - 1].l;
        bint tmp;
        tmp = s / a[i].r;
        if(ans < tmp){
          ans = tmp;
        }
      }
      ans.print();
    }
    
  • 相关阅读:
    浏览器低延时播放监控摄像头视频(EasyNVR播放FLV视频流)
    RTSP/Onvif摄像机在做H5无插件直播中遇到对接海康摄像机发送OPTIONS心跳的问题
    EasyDarwin系列互联网视频直播录像方案的选择
    EasyNVR配置需求
    EasyNVR硬件云终端与EasyNVR综合对比
    EasyNVR使用过程中问题的自我排查设备不在线问题自我排查检测
    EasyNVR在Linux系统下将录像文件与EasyNVR运行分离
    EasyNVR硬件云终端使用说明(问题的自我排查与解决)
    EasyNVR内网接入网关+EasyNVS云端管理平台,组件起一套轻量级类似于萤石云的解决方案
    EasyNVR支持的设备接入类型以及关于国标设备是否支持接入EasyNVR
  • 原文地址:https://www.cnblogs.com/FoxC/p/13546832.html
Copyright © 2011-2022 走看看