单调队列优化dp 20pts 求调
查看原帖
单调队列优化dp 20pts 求调
877691
MorLeaves楼主2024/8/15 10:40
#include<iostream>
#include<cstdio>
#include<queue>
typedef long long ll;
using namespace std;
ll n,m,k,p,x,y,z,a[4005][4005],dp[4005][4005],id[4005];
deque<ll> q;
int main()
{
	scanf("%lld %lld %lld %lld",&n,&m,&k,&p);
	for(ll i=1;i<=k;i++)
	{
		scanf("%lld %lld %lld",&x,&y,&z);
		a[x][y]=z;
	}
	for(ll i=1;i<=n;i++)
	{
		ll cnt=0;
		for(ll j=1;j<=m;j++)
		{
			while(!q.empty()&&dp[i-1][q.back()]<=dp[i-1][j])
			{
				q.pop_back();
				cnt--;
			}
			q.push_back(j);
			cnt++;
			while(!q.empty()&&cnt>2*p+1)
			{
				q.pop_front();
				cnt--;
			}
			id[j]=q.front();
		}
		for(ll j=1;j<=m;j++)
		{
			dp[i][j]=dp[i-1][id[min(j+p,m)]]+a[i][j];
		}
		for(ll j=1;j<=m;j++)
		{
			id[j]=0;
		}
		while(!q.empty())
		{
			q.pop_back();
		}
	}
	ll ans=-9e18;
	for(ll i=1;i<=m;i++)
	{
		ans=max(ans,dp[n][i]);
	}
//	for(ll i=1;i<=n;i++)
//	{
//		for(int j=1;j<=m;j++)
//		{
//			printf("%lld ",dp[i][j]);
//		}
//		printf("\n");
//	}
	printf("%lld",ans);
	return 0;
}
2024/8/15 10:40
加载中...