P2285 [HNOI2004] 打鼹鼠

[HNOI2004] 打鼹鼠

题目描述

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

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

输入格式

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

输出格式

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

样例 #1

样例输入 #1

2 2	         
1 1 1		
2 2 2

样例输出 #1

1

正解

一维 dp 足够了。

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

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

三、答案:最后的答案就是 max ⁡ ( d p [ 1 ] , d p [ 2 ] , d p [ 3 ] , … , d p [ 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;
}
  • 35
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用\[1\]和引用\[2\]的描述,题目中的影魔拥有n个灵魂,每个灵魂有一个战斗力ki。对于任意一对灵魂对i,j (i<j),如果不存在ks (i<s<j)大于ki或者kj,则会为影魔提供p1的攻击力。另一种情况是,如果存在一个位置k,满足ki<c<kj或者kj<c<ki,则会为影魔提供p2的攻击力。其他情况下的灵魂对不会为影魔提供攻击力。 根据引用\[3\]的描述,我们可以从左到右进行枚举。对于情况1,当扫到r\[i\]时,更新l\[i\]的贡献。对于情况2.1,当扫到l\[i\]时,更新区间\[i+1,r\[i\]-1\]的贡献。对于情况2.2,当扫到r\[i\]时,更新区间\[l\[i\]+1,i-1\]的贡献。 因此,对于给定的区间\[l,r\],我们可以根据上述方法计算出区间内所有下标二元组i,j (l<=i<j<=r)的贡献之和。 #### 引用[.reference_title] - *1* *3* [P3722 [AH2017/HNOI2017]影魔(树状数组)](https://blog.csdn.net/li_wen_zhuo/article/details/115446022)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [洛谷3722 AH2017/HNOI2017 影魔 线段树 单调栈](https://blog.csdn.net/forever_shi/article/details/119649910)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值