【题解】[牛客网NOIP赛前集训营-提高组(第四场)]C.灭虫 线性DP+堆优化

题目链接
在这里插入图片描述
在这里插入图片描述


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int N=3e3+10;
struct node{
	int p,l,r;
	bool operator <(const node&rhs)const{
	return p<rhs.p;}
}v[N];
int n,h[N*3],H,f[N][N*3],pre[N][N];
inline int ID(int p){return lower_bound(h+1,h+H+1,p)-h;}
int main()
{
	//freopen("in.txt","r",stdin);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	    scanf("%d%d%d",&v[i].p,&v[i].l,&v[i].r);
	for(int i=1;i<=n;i++)
	{
		h[++H]=v[i].p-v[i].l;
		h[++H]=v[i].p;
		h[++H]=v[i].p+v[i].r;
	}
	sort(v+1,v+n+1);sort(h+1,h+H+1);H=unique(h+1,h+H+1)-h-1;
	for(int i=1;i<=n;i++)
	{
		pre[i+1][i]=v[i].p;
		for(int j=i;j<=n;j++)
		    pre[i][j]=min(pre[i][j-1],v[j].p-v[j].l);
	}
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		int p=ID(v[i].p),l=ID(v[i].p-v[i].l);
		priority_queue<pair<int,int> >q;
		for(int k=1;k<=i;k++)
		    q.push({f[k-1][ID(pre[k+1][i])]-pre[k+1][i],v[k].p+v[k].r});
		for(int j=1;j<=H;j++)
		{
			f[i][j]=f[i][j-1];
			if(j<=p)f[i][j]=max(f[i][j],(j<l)?f[i-1][j]:(f[i-1][l]+h[j]-h[l]));
			else
			{
				while(q.size()&&q.top().second<h[j])q.pop();
				if(q.size())f[i][j]=max(f[i][j],q.top().first+h[j]);
			}
			ans=max(ans,f[i][j]);
		}
	}
	printf("%d\n",ans);
	return 0;
}

总结

线性DP好题

猜你喜欢

转载自blog.csdn.net/qq_41958841/article/details/83550389