【CF1201C】最大の中央値

質問の意味:

N- $の$配列の長さ、および$ K $操作を取得する機会を与え、そして各オペレーションは$値を$ 1の前記数を追加することです。

$ K $シーク動作を合理的な取り決め、中央値、最大の結果のシーケンスように。

$ 1 \ nは\ * 2 5.1 10 ^ \ K \ 10 ^ 9 $

分析:

私たちは、操作の中央値よりも小さくなるように、元のシーケンス番号が、その答えは確かに最善ではない場合、それはより大きな数字に優れている、貪欲な戦略になりたいです。

そこで、我々はすべて、このシーケンス番号で削除することができます中央値未満です。

オリジナルの中央値がはるかにそのシーケンスの中で最も小さい番号になることを削除した後。

問題は、「最小最大」にこの種の問題に変換され、はい、あなたは半分の答えをすることができます。

我々は確かに可能な最小数に動作する必要がありませんが、一度他の数を超え、この数は、もはや最小の数です。

したがって、我々は、一例として以下の図を分析する必要があります。

私たちは、$ 1 $は、できるだけ大きなドットたい、そして、彼らはナンバーワンに操作の数を指すことになり支払わなければならないが、同時に、数字が大きくないより$ 1 $、他の数であることを保証するために。

そこで、我々は、2で割った(すなわち答え)非常に次のようになります。

あなたは$ 1したい場合は$にあなたがしたいので、二つの層を充填ドット:

したがって、$ 1 $の操作が必要。

あなたは3点番号に満たされた$ 1 $をしたい場合は、次の操作を行います。

それは$ 1 + $ 3 = 4演算の合計を必要とします。

そのため、テストを決定するためにすべての条件を見ていることは、ドットの高さの差の高さよりも小さいかどうかより$ k個まで追加です。$

この方法では、コードを書くことができます。

書式#include <アルゴリズム> 
書式#include <cstdioを> 
typedefの長い 長いLL。

LL N、K、[ 200010 ]、ANS、L、R。

ブールチェック(LLのX){ 
    LL和 = 0 (LL i = 1 ; iが<= N; iが++ 場合([i]の< X)
            の和 + = X - [I]。//算高度差之和
         
            破ります戻り和<= K。//检验条件
} 

int型のmain(){ 

    scanf関数(" %のLLDの%のLLD "、&​​N、&; K)
     のための(LL I = 1 I <= N; I ++の
        scanfの(" %のLLD "、&​​A [I]); 
    STD ::ソート(A + 1、A + N-+ 1 ); //注意二部単調性、従ってソートする

    N N / = 2 + 1 //便宜上、ここで事前変化Nゲージ;
     のための(LL I = 1 ; Iは<= nであり; Iは++ 
        [I]は = [N + I - 1 ]; 

    L = 1、= R&LT 2E9;
     ながら(L < R&LT){ 
        LL MID =(L + R&LT + 1。)>> 1 もし(チェック(MID))L = ミッド。
        他の R =中旬- 1 
    } 

    のprintf(" %LLDする\ n " 、L)。

    リターン 0 ; 
}

複雑$ \テキスト{O(Nログn)}。$


また、この質問は、などの貪欲(線形複雑度)など、他の慣行は、ありますが、ここで説明されていない、あなたが見て行くことができます興味を持っています。

 

おすすめ

転載: www.cnblogs.com/zengpeichen/p/11515613.html