1 条题解
-
9
反悔贪心。
先建链表,每次找最大的,把他拿出来,如果标记过就跳过,然后为了反悔把“左边的+右边的-当前的”放进去,最后把他左右两边相邻的标记掉,再把他左指针连上左边的左边,他的右指针连上右边的右边。现在再把左边的右指针连他,右边的左指针连他,就做完了。
#include<bits/stdc++.h> #define int long long #define R(x) x=read() #define N 200005 using namespace std; inline int read() { int x=0,y=1; char e=getchar(); while(e<'0'||e>'9') { if(e=='-')y=-1; e=getchar(); } while(e>='0'&&e<='9') { x=(x<<1)+(x<<3)+(e-'0'); e=getchar(); } return x*y; } int n,k,a[N]; int lst[N],nxt[N]; bool vis[N]; priority_queue<pair<int,int> >q; signed main() { R(n),R(k); for(int i=1; i<=n; ++i) { R(a[i]),lst[i]=i-1,nxt[i]=i+1; if(i==1)lst[i]=n; if(i==n)nxt[i]=1; q.push({a[i],i}); } if(n/2<k) { cout<<"No solution!\n"; return 0; } int cnt=0,ans=0; while(!q.empty()&&cnt<k) { int i=q.top().second; if(vis[i]) { q.pop(); continue; } ++cnt,ans+=q.top().first; q.pop(); vis[lst[i]]=1,vis[nxt[i]]=1; a[i]=a[lst[i]]+a[nxt[i]]-a[i]; q.push({a[i],i}); nxt[i]=nxt[nxt[i]],lst[i]=lst[lst[i]]; lst[nxt[i]]=i; nxt[lst[i]]=i; } cout<<ans; return 0; }
- 1
信息
- ID
- 75
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 7
- 标签
- (无)
- 递交数
- 45
- 已通过
- 10
- 上传者