P2285 [HNOI2004] 打鼹鼠

[HNOI2004] 打鼹鼠

题目描述

鼹鼠是一种很喜欢挖洞的动物,但每过一定的时间,它还是喜欢把头探出到地面上来透透气的。根据这个特点阿牛编写了一个打鼹鼠的游戏:在一个 n×nn \times nn×n 的网格中,在某些时刻鼹鼠会在某一个网格探出头来透透气。你可以控制一个机器人来打鼹鼠,如果 iii 时刻鼹鼠在某个网格中出现,而机器人也处于同一网格的话,那么这个鼹鼠就会被机器人打死。而机器人每一时刻只能够移动一格或停留在原地不动。机器人的移动是指从当前所处的网格移向相邻的网格,即从坐标为 (i,j)(i, j)(i,j) 的网格移向 (i−1,j),(i+1,j),(i,j−1),(i,j+1)(i-1, j), (i+1, j), (i, j-1), (i, j+1)(i1,j),(i+1,j),(i,j1),(i,j+1) 四个网格,机器人不能走出整个 n×nn \times nn×n 的网格。游戏开始时,你可以自由选定机器人的初始位置。

现在知道在一段时间内,鼹鼠出现的时间和地点,请编写一个程序使机器人在这一段时间内打死尽可能多的鼹鼠。

输入格式

第一行为 n,mn, mn,mn≤1000n \le 1000n1000m≤104m \le {10}^4m104),其中 mmm 表示在这一段时间内出现的鼹鼠的个数,接下来的 mmm 行中每行有三个数据 time,x,y\mathit{time}, x, ytime,x,y 表示在游戏开始后 time\mathit{time}time 个时刻,在第 xxx 行第 yyy 个网格里出现了一只鼹鼠。time\mathit{time}time 按递增的顺序给出。注意同一时刻可能出现多只鼹鼠,但同一时刻同一地点只可能出现一只鼹鼠。

输出格式

仅包含一个正整数,表示被打死鼹鼠的最大数目。

样例 #1

样例输入 #1

2 2	         
1 1 1		
2 2 2

样例输出 #1

1

正解

一维 dp 足够了。

一、状态:虽然题目中给出每个鼹鼠出来都会有三个参数 time,x,ytime,x,ytime,x,y,但是只需要把一个鼹鼠整体看就可以了,也就是 dp[i]dp[i]dp[i] 代表打到第 iii 个鼹鼠最多打的个数。

二、转移:还是需要先初始化的,dp[i]=1dp[i]=1dp[i]=1,表示最后会打到这个鼹鼠。然后就是一层循环,遍历 j=1j=1j=1i−1i-1i1,表示抓第 iii 个鼹鼠之前被抓住的鼹鼠。接下来就是判断条件,因为需要在下一个鼹鼠来临前打掉,所以需要现在的位置到准备打的鼹鼠的距离 ≤\le 两个鼹鼠出现的时间之差,即 if⁡(∣x[i]−x[j]∣+∣y[i]−y[j]∣≤time[i]−time[j])\operatorname{if}(|x[i]-x[j]|+|y[i]-y[j]|\le time[i]-time[j])if(x[i]x[j]+y[i]y[j]time[i]time[j]),这时 dp[i]=max⁡(d[i],dp[j]+1)dp[i]=\max(d[i],dp[j]+1)dp[i]=max(d[i],dp[j]+1),多抓一个鼹鼠。

三、答案:最后的答案就是 max⁡(dp[1],dp[2],dp[3],…,dp[n])\max(dp[1],dp[2],dp[3],\dots,dp[n])max(dp[1],dp[2],dp[3],,dp[n])

代码

#include <bits/stdc++.h>
//#define int long long
using namespace std;

const int M = 10010;
int t[M],x[M],y[M];

int n,m,mx;
int dp[M];

void solve()
{
	cin >> n >> m;
	for (int i = 1;i <= m;i++)
		cin >> t[i] >> x[i] >> y[i];
	for (int i = 1;i <= m;i++)
	{
		dp[i] = 1;
		for (int j = 1;j < i;j++)
			if (abs(x[i]-x[j])+abs(y[i]-y[j]) <= t[i]-t[j])
				dp[i] = max(dp[i],dp[j]+1);
	}
	for (int i = 1;i <= m;i++)
		mx = max(mx,dp[i]);
	cout << mx;
}

signed main()
{
	solve();
	printf("\n");
	return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值