興味深い疑問---思考の一種、列挙

 

  この質問学校の兄を食べるために、学校の兄への道を進んでいるが、私は非常に興味深いと感じ、聞くと言うが、(私が質問を磨くための時間を持っている、と〜少し愚かではない場合があります)思考の多くを必要と

  これによって、それを記録します。

 

 問題:

    (x、y)の組がnあり、Kタプルから要求を除去最大値を乗算したkタプルのX(和は、(X)* minは、Y(Yの最小値)になるようにKタプル)

 

 解決:

    大列挙に小さな次いで、各y値をy値を昇順でソートNタプルは、Yの電流値の最小値は、kのタプルを選択すると、現在のタプルで、次いでKタプル(定電流前記タプル)の後。すなわち、K-1の組から現在のタプル後のXの最大値に対応するを選択する必要がある、K-1が決定されていないがタプルれます。だから問題は、K-1の最大数を取るために、現在のタプルに低減されます。sum_i(X)* min_i(y)を算出し、iが最大値が正解である、現在のタプルのインデックスです。

    列挙の転送速度を上げるために、我々は、私はK-1であり、xの最大の1-Nを+2タプルの集合を維持します。SET2 K-1最大Xに格納され、残りのX(インデックス= I + 1〜Nタプル)に格納されているSET1ので、タプルを決定するために必要な転送時間[I + 1] SET1か.X、直接除去し、そうでない場合は定数でSET2、それを排除し、SET1 Xを除去する必要性を除去した後、もちろん、最大のx SET1から取り除く必要があります。

 

 コードは以下の通りであります:

#include <iostreamの> 
する#include <アルゴリズム> 
の#include < ストリング > 
の#include < SET >
 使用して 名前空間STD;
 // 問題:N(x、y)の組があり、Kタプルから要求を削除、Kようタプルxおよびyは、(SUM(X)*分(最大値の最小値が乗算される k個のY) タプル)
 // 対処:yの値を昇順でソートのn-タプル次いで、各Y値の列挙を昇順、Yの電流値の最小値は、kのタプルを選択し、次いでKタプルは(タプルが現在含まれている必要があります)現在のタプルの後に配置されています。こと
 //             K-1が決定されていない存在タプルは、K-1の組から現在のタプル後のXの最大値に対応するを選択する必要があります。だから問題は、K-1の最大数を取るために、現在のタプルに低減されます。sum_i(X)* min_i(Y算出 )、iは現在のタプル
 //           インデックス、最大値が正解であるとります。
@             列挙の転送速度を向上させるために、我々は2つのタプルI + K-1の最大の1-NおよびXのセットを維持します。SET2 SET1残りX(インデックス= I + 1〜に格納され、K-1の最大Xに格納された N そう移し、タプル)
 //            必要なタプルを決定[I + 1] SET1か.X、直接除去し、そうでなければ一定でSET2、それを排除し、SET1 Xを除去する必要性を除去した後、もちろん、最大のx SET1から取り除く必要があります。
CONSTの INT N = 1E5 + 5。; 
typedefの対は < INTINT > タプル;
 BOOL CMP(CONSTタプルA、CONST タプルB){
     戻り a.second < b.second; 
} 
多重集合 < 整数 > S1、S2、
多重集合 < INT > :: ITをイテレータ、
多重集合 < INT > :: reverse_iterator RITと、

int型のmain()
{
    int型 N、K。CIN >> N >> K。
    タプルデータ[N]。
    以下のためにint型 i = 0 ; iがn <; iは++ ){ 
        CIN >>データ[i]が1次回>> データ[I] .second。
    } 
    ソート(データ、データ + N、CMP)。
    以下のためにint型私= 1 ; iがN <; Iは++ ){ 
        s1.insert(データ[i]が1次回)。
    } 
    INT ANS = 0 int型の合計= 0 ;
    以下のためにint型 i = 1 ; iはK <; iは++ ){
        int型 MAX_VAL = * s1.rbegin(); 
        s1.erase(s1.find(MAX_VAL))。
        s2.insert(MAX_VAL)。
        合計 + = MAX_VAL。
    } 
    のためのint型 I = 0 ; iがK-+ 1 <Nを; iが++ ){ 
        ANS = MAX(ANS、データ[I] .second *(和+ DATA [i]が1次回))。
        もし(N - I == k)を破りますもし(s1.count(データ[iが+ 1 ] 1次回)> 0 ){  s1.find =(データ[I + 1 ] 1次回)。
            s1.erase(それ)。
        }
        { 
            それは s2.find =(データ[I + 1 ] 1次回)。
            合計 - = * それ。
            s2.erase(それ)。

            RIT = s1.rbegin()。
            合計 + = * RIT。
            s2.insert( * RIT)。
            s1.erase(s1.find( * RIT)); 
        } 
    } 
    のstd :: COUT << " 回答= " << ANS << ENDL。
    リターン 0 ; 
} 

/ * 
5 2 
2 3 
4 1 
5 7 
1 3
6 3 
* /

 

おすすめ

転載: www.cnblogs.com/chen9510/p/11613849.html