Snuke Panic (1D)

Problem Statement

Takahashi is trying to catch many Snuke.

There are five pits at coordinates 00, 11, 22, 33, and 44 on a number line, connected to Snuke's nest.

Now, NN Snuke will appear from the pits. It is known that the ii-th Snuke will appear from the pit at coordinate X_iXi​ at time T_iTi​, and its size is A_iAi​.

Takahashi is at coordinate 00 at time 00 and can move on the line at a speed of at most 11.
He can catch a Snuke appearing from a pit if and only if he is at the coordinate of that pit exactly when it appears.
The time it takes to catch a Snuke is negligible.

Find the maximum sum of the sizes of Snuke that Takahashi can catch by moving optimally.

Constraints

  • 1 \leq N \leq 10^51≤N≤105
  • 0 < T_1 < T_2 < \ldots < T_N \leq 10^50<T1​<T2​<…<TN​≤105
  • 0 \leq X_i \leq 40≤Xi​≤4
  • 1 \leq A_i \leq 10^91≤Ai​≤109
  • All values in input are integers

        题目大意就是在t[i]时刻在x[i]位置会出现一个体长a[i]的物体,然后需要控制一秒最多移动一个单位的物体去吃掉出现的物体,并且要使得吃掉物体的总长尽可能大。

         因为移动的范围实际上很小,总共只有5个单位长度(0-4),因此可以考虑暴力更新的思想,在相邻的两个时间内有着 det=t[i]-t[i-1] 的时间间隔,在这段时间内每个单元的takahashi(实际上是前面一系列最操作之后在这个位置的takahashi的最优配置)都可以移动到这个单元半径为det的单元格内,并且把这个单元格的已有长度带过去,如果可以更大那么就更新掉到达的位置,也就是覆盖掉。更新完之后就是物体出现之前的一瞬间的当前最优配置,这时候物体出现,只需要在相应位置给这个位置的takahashi加上长度,需要注意的就是加长度也要注意位置和时间的关系,至少要满足可以到达的条件才可以直接加上长度。

代码如下:

#include<stdio.h>
#include<algorithm>
using namespace std;
#define ll long long
int t[200000];
int x[200000];
int a[200000];
ll ans[10];
ll tmp[10];
int main()
{
	int n; scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d%d%d", t + i, x + i, a + i);
	}
	for (int i = 0; i < 5; i++) 
	{
		ans[i] = 0;//初始化
	}
	t[0] = 0;
	for (int i = 1; i <= n; i++)
	{
		int det = t[i] - t[i - 1];//计算时间间隔,也就是这段时间的扩散范围
		//printf("det=%d\n", det);
		for (int j = 0; j <= 4; j++)
		{
			tmp[j] = ans[j];//暂存,因为是要和更新之前的比较
		}
		for (int j = 0; j <= 4; j++)//逐点扩散
		{
			for (int k = max(0, j - det); k <= min(4, j + det); k++)
			{
				ans[k] = max(ans[k], tmp[j]);//和j位置的比较,因为是从j位置扩散过来的
			}
		}
		if(t[i]>=x[i])//必须要可以到达
			ans[x[i]] += a[i];//吃到
	}
	ll res = 0;
	for (int i = 0; i <= 4; i++)
	{
		res = max(res, ans[i]);//找出最大值
	}
	printf("%lld\n", res);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_60360239/article/details/127251858