zoukankan      html  css  js  c++  java
  • ZOJ 2968 Difference Game 【贪心 + 二分】

    题意:
    有Ga、Gb两堆数字,初始时两堆数量相同。从一一堆中移一一个数字到另一一堆的花费定义为两堆之间数
    量差的绝对值,初始时共有钱C。求移动后Ga的最小小值减Gb的最大大值可能的最大大值。
    思路:
    假如有足足够钱移动,那么Ga的最大大值和Gb的最小小值应该是两堆合并后排序中相邻的两数。那么我们
    就枚举这个数。枚举的时候我们需要确定形成这个情况(大大的都在Ga堆,小小的都在Gb堆)的最少花
    费,这个花费可以这样解决,假设Ga中向Gb中需要移入入ab个数,Gb需要向Ga移入入ba个数,首首先当
    然是Ga移一一个给Gb,然后Gb移一一个给Ga,这样直到某一一堆需要移出都移出停止止,此时的花费就是
    2*min(ab,ba)。接着就是其中一一堆一一直移给另一一堆,每移一一次费用用会增2,所以此时的花费为
    |ab-ba|*(|ab-ba|-1)。总花费就为2*min(ab,ba) + |ab - ba| *(|ab -ba|- 1)。
    当然可能没有足足够钱移动,Ga堆的最小小值永远小小于Gb堆的最大大值,这样我们当然要把Ga堆前C/2
    (C/2+1)小小的移到Gb堆,Gb堆前C/2+1(C/2)的移到Ga堆,当然是交替移。

    By @sake

      

    Source Code:

    //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
    #include <stdio.h>
    #include <iostream>
    #include <fstream>
    #include <cstring>
    #include <cmath>
    #include <stack>
    #include <string>
    #include <map>
    #include <set>
    #include <list>
    #include <queue>
    #include <vector>
    #include <algorithm>
    #define Max(a,b) (((a) > (b)) ? (a) : (b))
    #define Min(a,b) (((a) < (b)) ? (a) : (b))
    #define Abs(x) (((x) > 0) ? (x) : (-(x)))
    #define MOD 1000000007
    #define pi acos(-1.0)
    
    using namespace std;
    
    
    int ga[20010], gb[20010], gc[50000];
    bool cmp(const int & a, const int &b){
        return a > b;
    }
    //二分查找,关键字key,右边界n,左边界默认-1
    int b_search(int key, int n){
        int l = -1, r = n, m;
        while (l+1 < r) {
            m = (l+r)/2;
            if (ga[m] < key) {
                l = m;
            } else {
                r = m;
            }
        }
        return r;
    }
    int main(){
        int t;
        scanf("%d", &t);while (t--) {
            int n, cost;
            scanf("%d%d", &n, &cost);
            for (int i = 0; i < n; i ++) {
                scanf("%d", &ga[i]);
                gc[i] = ga[i];
            }
            for (int i = 0; i < n; i ++) {
                scanf("%d", &gb[i]);
                gc[i+n] = gb[i];
            }
            if (n == 1) {
                printf("%d
    ", ga[0] - gb[0]);
                continue;
            }
            sort(ga, ga+n);
            sort(gc, gc+2*n);
            sort(gb, gb+n, cmp);
            int maxn = -50000;
            for (int i = 1; i < 2*n; i ++) {
                int ab = b_search(gc[i], n);
                int ba = (2*n - i) - (n - ab);
                int mab = min(ab, ba);
                int fab = abs(ab-ba);
                int c = 2*mab + (fab-1)*fab;
                if (c <= cost) {
                    maxn = max(maxn, gc[i]-gc[i-1]);
                }
            }
            if (maxn > 0) {
                printf("%d
    ", maxn);
            } else {
                int ans = max(ga[cost/2]-gb[cost/2+1], ga[cost/2+1]-gb[cost/2]);
                printf("%d
    ", ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    澄净是什么意思?
    【Cavali风格/优质羊毛混纺面料/高密抗静电里衬/撞色拼皮/立领/绿色/便装单西】玛萨玛索男装网购商城
    【100%纯新美利奴羊毛(除装饰材料外)/半高领/丈青/商务毛衫】玛萨玛索男装网购商城
    victim是什么意思_victim在线翻译_英语_读音_用法_例句_海词词典
    Lind.DDD.Repositories.EF层介绍
    Lind.DDD.Domain领域模型介绍
    大叔也说Xamarin~Android篇~原生登陆与WebView的网站如何共享Session
    Redis学习笔记~Redis并发锁机制
    知方可补不足~sqlserver中对xml类型字段的操作
    json转String 和 String转json 和判断对象类型
  • 原文地址:https://www.cnblogs.com/wushuaiyi/p/4393732.html
Copyright © 2011-2022 走看看