这题首先上来会发现题目中的很多信息都是假的,核心就是问要构造一个\(x\)个点的完全图至少要多长的序列
我们把序列中相邻的两个元素看作图上的一条边,则可以把问题转化为:给一个\(x\)个点的完全图,问至少要走多长的路径才可以遍历图中的所有边至少一次
简单讨论下会发现当\(x\)为奇数时,此时图中每个点的度数\(x-1\)为偶数,因此这个图一定存在欧拉回路,故可以恰好经过所有边一次,对应的序列长度为\(\frac{x\times (x-1)}{2}+1\)
而当\(n\)为偶数时,手玩下会发现先把每个点度数拿出\(x-2\)来走一个欧拉回路,然后剩下每个点的一条边就直接串成一条链即可,对应的序列长度为\(\frac{x\times (x-2)}{2}+x-1+1=\frac{x^2}{2}\)
因此最后我们直接暴力枚举最后选了多少个数,然后贪心选大的即可
#include<cstdio>
#include<iostream>
#include<utility>
#include<vector>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<set>
#include<array>
#include<random>
#include<bitset>
#include<ctime>
#include<limits.h>
#include<assert.h>
#include<unordered_set>
#include<unordered_map>
#define int long long
#define RI register int
#define CI const int&
#define mp make_pair
#define fi first
#define se second
#define Tp template <typename T>
using namespace std;
typedef long long LL;
typedef long double LDB;
typedef unsigned long long u64;
typedef __int128 i128;
typedef pair <int,int> pi;
typedef vector <int> VI;
typedef array <int,3> tri;
const int N=100005;
int n,m,x,w[N],ans;
signed main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
RI i; for (scanf("%lld%lld",&n,&m),i=1;i<=m;++i) scanf("%lld%lld",&x,&w[i]);
for (x=0,i=1;i<=m;++i)
{
int tmp=i&1?i*(i-1)/2LL+1:i*i/2LL;
if (tmp<=n) x=i; else break;
}
for (sort(w+1,w+m+1,greater <int>()),i=1;i<=x;++i) ans+=w[i];
return printf("%lld",ans),0;
}
标签:typedef,frac,int,Sereja,long,Numbers,include,CF367C,define
From: https://www.cnblogs.com/cjjsb/p/17775579.html