題意:
給出m個不同的數,並且每個數都有個費用,現在要在m個數中選擇一些數(每個數可使用任意多次),用這些數組成一個長度爲n的數列,並且滿足任意兩個不同種類的數都相鄰。問最大的費用是多少。
題解:
關鍵在於確定:使數列中有k個不同的數,數列的最小長度是多少。由於任意兩個不同種類的數都相鄰,聯想到完全圖的歐拉回路,即走過多少條邊可以使每條邊都經過一次,顯然次數+1就是最小長度。有奇數個點的時候可以一筆畫,只需(k-1)*k/2次即可,如果是偶數則需要額外的(k-2)/2次。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int n,m,val[N];
int check(int mid) {
int x=mid*(mid-1)/2;
if (mid%2==0) x+=(mid-2)/2;
return n>=x+1;
}
signed main() {
cin>>n>>m;
for (int i=1;i<=m;i++) {
int x,y; cin>>x>>y;
val[i]=y;
}
sort(val+1,val+m+1);
int l=1,r=m;
while (l<r) {
int mid=(l+r+1)>>1;
if (check(mid)) l=mid;
else r=mid-1;
}
int ans=0;
for (int i=1;i<=l;i++) ans+=val[m-i+1];
cout<<ans;
return 0;
}