CF 367Cセレハと数字の配置

https://codeforces.com/problemset/problem/367/C

タイトル

あなたにはm個の数があり、各数には無限の数があります。これらの数値を使用して、長さnの配列aを形成します。お願い

  1. 数xと数yが選択されている場合、2つの数は配列の少なくとも1つの位置で隣接します。iが存在するため、a [i] = xおよびa [i + 1] = y、またはa [i] = yおよびa [i + 1] = x

配列の値は、配列を構成する数値の値によって決まります。i番目の数値の値はv [i]です。

空の配列の値は0です。1からmまでのiを考慮してください。i番目の数値が表示される場合、配列の値は+ vになります[i]

配列の値を最大化するために配列を形成する方法を尋ねます

$ 1 \ leqslant n \ leqslant 2 \ times10 ^ 6、1 \ leqslant m \ leqslant 10 ^ 5 $

$ 1 \ leqslant v_i \ leqslant 10 ^ 5 $

解決策

選択した数値をグラフに描画します。すべての数値は2つのエッジを2つずつ接続する必要があり、問題はすべてのエッジを最小のステップで歩く方法です。

それからオイラーの質問になります

オイラー道路を形成するために必要かつ十分な条件は、次のとおりです。次数が奇数のポイントが最大で2つあり、残りは次数が偶数のポイントです。

オイラーループを形成するために必要かつ十分な条件は、すべての点が次数が等しい点であることです。

オイラー道路またはオイラー回路を形成できない場合は、隣接する数値が1回だけ出現する必要がなく、最後にシーケンスを取得できるため、エッジを追加する必要があります。

n個の数によって形成されるエッジの数は

\ [\ frac {n \ cdot(n-1)} {2} \]

各ポイントの次数は$ n-1 $です

nが奇数の場合、オイラーループを形成でき、配列の長さはエッジの数と等しくなります。

nが偶数の場合、すべてのポイントの次数は奇数になります。n> 2の場合、$ \ frac {n} {2} -1 $エッジを追加して、$ n-2 $ポイントの次数が+1になるようにする必要があります。偶数、オイラー道路を形成するためにn = 2の場合は0エッジを追加

これは、明らかに要件を満たす最小の長さの配列です。1つ少ない場合、すべてのエッジをトラバースすることはできません。1つ以上ある場合は、最小の長さであってはなりません。

だからあなたは$ O(m)$で最も多くの数を得ることができ、それから合計に貪欲です

時間の複雑さ$ \ mathcal {O}(m \ log m)$

ACコード

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define REP(i、a、b)for(int i =(a); i <(b); i ++)
#define REPE(i、a、b)for(int i =(a); i <=(b); i ++)
#define PERE(i、a、b)for(int i =(a); i> =(b); i--)
名前空間stdを使用します。
typedef long long ll;
#define MAXM 100007
int arr [MAXM];
inline bool cmp(int a、int b){return a> b;}
int main(){
	int n、m; scanf( "%d%d"、&n、&m);
	REP(i、0、m)scanf( "%* d%d"、&arr [i]);
	sort(arr、arr + m、cmp);
	int ch = -1; ll ans = 0;
	PERE(x、m、1){
		ll t = ll(x)*(x-1)/ 2;
		if((x&1)== 0)t + = x / 2-1;
		if(t <n){ch = x; break;}
	}
	REP(i、0、ch)ans + = arr [i];
	printf( "%lld \ n"、ans);
}

 

おすすめ

転載: www.cnblogs.com/sahdsg/p/12722442.html