この質問学校の兄を食べるために、学校の兄への道を進んでいるが、私は非常に興味深いと感じ、聞くと言うが、(私が質問を磨くための時間を持っている、と〜少し愚かではない場合があります)思考の多くを必要と
これによって、それを記録します。
問題:
(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の対は < INT、INT > タプル; 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 * /