P1484 种树(反悔贪心,链表合并)

题目链接

d p . . . . . . . . . . 被dp蒙蔽了我的双眼..........

i , i 1 i + 1 假如我们一开始选第i个坑种树,那么i-1和i+1就不能选了

i , i 1 i + 1. 假如不选i,那就选i-1和i+1.

具体操作是把所有坑扔到优先队列中,假设当前拿出的最大坑是x

x ( , ) 直接把x选掉(后续可能会反悔,暂时选)

i 1 i + 1 a i 1 + a i + 1 a i 那么i-1和i+1合并成a_{i-1}+a_{i+1}-a_i

? , i i 1 i + 1 什么意思?假如下次拿到这个值,代表不选i而选i-1和i+1

一直这样做就好了

神仙题

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=5e5+10;
struct p{
	ll v,id;
	bool operator < (const p&tmp )	const{
		return v<tmp.v;
	}
};
priority_queue<p>q;
ll a[maxn],l[maxn],r[maxn],n,m,ok[maxn],ans;
int main()
{
	cin >> n >> m;
	for(int i=1;i<=n;i++)
	{
		cin >> a[i];
		l[i]=i-1,r[i]=i+1;
		q.push( (p){a[i],i} );
	}
	r[0]=1,l[n+1]=n;
	while( m-- )
	{
		while( ok[q.top().id] )	q.pop();
		p t=q.top(); q.pop();
		if( t.v<0 )	break;		
		ans+=t.v;//加上贡献 
		int x=t.id;
		a[x]=a[ l[x] ]+a[ r[x] ]-a[x];
		t.v=a[x];
		ok[l[x]]=ok[r[x]]=1;
		l[x]=l[l[x]],r[l[x]]=x;
		r[x]=r[r[x]];l[r[x]]=x;
		q.push(t);
	}
	cout<<ans;
}

猜你喜欢

转载自blog.csdn.net/jziwjxjd/article/details/107413774
今日推荐