[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)(i−1,j),(i+1,j),(i,j−1),(i,j+1) 四个网格,机器人不能走出整个 n×nn \times nn×n 的网格。游戏开始时,你可以自由选定机器人的初始位置。
现在知道在一段时间内,鼹鼠出现的时间和地点,请编写一个程序使机器人在这一段时间内打死尽可能多的鼹鼠。
输入格式
第一行为 n,mn, mn,m(n≤1000n \le 1000n≤1000,m≤104m \le {10}^4m≤104),其中 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=1 到 i−1i-1i−1,表示抓第 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;
}

417

被折叠的 条评论
为什么被折叠?



