NEFU OJ Problem1485 贪吃蛇大作战 题解
- Problem:F
- Time Limit:1000ms
- Memory Limit:65535K
题目
Description
贪吃蛇大家一定都玩过吧,现在宋哥也要玩这个游戏,最初的时候贪吃蛇从屏幕的左下角出发,但是有一个非常不幸的事情,就是宋哥的游戏机的左键和下键坏掉了,这意味着什么?没错!他只能操控他的蛇向右或向上走了,假设屏幕被划分为109*109的格子,而贪吃蛇从坐标为(1,1)的格子出发,每次操作可以从坐标为(x,y)的格子前往坐标为(x+1,y)或(x,y+1)的格子,在所有格子中有一些格子中有一些食物,宋哥现在想知道,他的贪吃蛇最多能吃到多少食物呢?
Input
输入的第一行包含一个数字T(1<=T<=10),代表数据组数,之后的每组数据的每一行包含一个数字n (1<=n<=1000),代表有食物的格子数量,之后的n行每一行包含三个数字xi(1<=xi<=109),yi(1<=xi<=109),pi(1<=xi<=10^6),分别代表格子的坐标和在这个格子里的食物数量。
Output
输出T行,第i行为第i组数据的答案。
Sample Input
2
3
1 1 1
2 2 2
3 3 3
3
1 3 1
2 2 2
3 1 3
Sample Output
6
3
Hint
Source
MGH
思路
看起来像很经典的dp问题,但是区别是点很稀疏,只有1e3的点,却有1e9*1e9的棋盘,考虑将点位置重新紧密排布, 建立一个映射将稀疏点集\(S\)映射到紧密点集\(P'\)即 \(f:\{P_i = (X_i,Y_i)\in S\}\rightarrow \{P'_i=(X'_i,Y'_i)\in S'\}\)使得\(S'\)方便使用dp。
需要保证重新排布后性质不变,分析后得知需要满足保持原本的横纵坐标的大小关系即
\left\{
\begin{array}{c}
x_i < x_j \rightarrow x'_i < x'_j\\
x_i = x_j \rightarrow x'_i = x'_j\\
x_i > x_j \rightarrow x'_i > x'_j\\
\end{array}
\right.
\]
\left\{
\begin{array}{c}
y_i < y_j \rightarrow y'_i < y'_j\\
y_i = y_j \rightarrow y'_i = y'_j\\
y_i > y_j \rightarrow y'_i > y'_j\\
\end{array}
\right.
\]
如下图所示方法,删除所有空行和空列可以实现。



算法实现
- 对\(x\)坐标
由小到大排序 - 对于每个点
遍历从0开始分配新的\(x'\)坐标,如果某个点\(x\)坐标与上一个点相同,则分配相同的\(x'\)坐标,而不递增\(x'\)。
之后再对\(y\)坐标进行同样的操作。
完成后对\(S'\)点集进行DP即可
代码如下
#include <bits/stdc++.h>
using namespace std;
struct Food
{
int x, y, v, _x, _y;//_x和_y代表映射后坐标
} food[1020];
int mp[1020][1020], dp[1020][1020];
bool Cmp1(Food f1, Food f2)//x排序
{
return f1.x < f2.x;
}
bool Cmp2(Food f1, Food f2)//y排序
{
return f1.y < f2.y;
}
int Find(int x, int y)//Dp
{
if(dp[x][y] != -1)
return dp[x][y];
int res = 0;
if(x-1 >= 0)
res = max(res, Find(x-1,y));
if(y-1 >= 0)
res = max(res, Find(x,y-1));
return dp[x][y] = res + mp[x][y];
}
int main()
{
int T;
cin >> T;
while(T--)
{
int n;
cin >> n;
for (int i = 0; i < n; i ++)
scanf("%d%d%d", &food[i].x, &food[i].y, &food[i].v);
//x排序并分配新坐标
sort(food, food+n, Cmp1);
int ind_x = 1;
food[0]._x = 1;
for (int i = 1; i < n; i ++)
if(food[i].x == food[i-1].x)
food[i]._x = ind_x;
else
food[i]._x = ++ind_x;
//y排序并分配新坐标
sort(food, food+n, Cmp2);
int ind_y = 1;
food[0]._y = 1;
for (int i = 1; i < n; i ++)
if(food[i].y == food[i-1].y)
food[i]._y = ind_y;
else
food[i]._y = ++ind_y;
//普通DP过程
for (int i = 0; i <= 1000; i ++)
for (int j = 0; j <= 1000; j ++)
mp[i][j] = 0;
for (int i = 0; i < n; i ++)
mp[food[i]._x][food[i]._y] = food[i].v;
for (int i = 0; i <= ind_x; i ++)
for (int j = 0; j <= ind_y; j ++)
dp[i][j] = -1;
dp[0][0] = 0;
cout << Find(ind_x,ind_y) << endl;
}
return 0;
}
NEFU OJ Problem1485 贪吃蛇大作战 题解的更多相关文章
- Unity3D游戏贪吃蛇大作战源码休闲益智手机小游戏完整项目
<贪吃蛇大作战>一款休闲竞技游戏,不仅比拼手速,更考验玩家的策略. 视频演示: http://player.youku.com/player.php/sid/XMzc5ODA2Njg1Ng ...
- 贪吃蛇大作战canvas实现(手机触屏操作)--地图逻辑
//html部分 <!DOCTYPE html><html><head lang="en"> <meta charset="UT ...
- [Untiy]贪吃蛇大作战(五)——游戏主界面
接着上一节: 4.AI蛇的设计 这里AI蛇大部分代码都可以参照主角的代码,我这里的实现其实还可以进行改进.基本原理就是蛇创建之后给蛇一个随机方向的单位向量,AI蛇的蛇头添加一个比蛇头大两三倍大小的碰撞 ...
- [Untiy]贪吃蛇大作战(四)——游戏主界面
游戏主界面: 由于这个场景比较复杂,需要分几个部分实现: 1.游戏背景 首先我们的游戏场景上包括了一个大的背景图片,之外再包围一个红色的区域.中间的区域才是可活动的区域,周围通过碰撞检测盒来检测是否有 ...
- [Untiy]贪吃蛇大作战(三)——商店界面
游戏商店界面: 实际的效果图如下: 要实现这个滑动,首先我们需要,一个内容显示区域,一个内容滚动区域,如下图: 其中ItemContent挂载的组件如下: 红框标注的地方是右方的滑动块. 然后Item ...
- [Untiy]贪吃蛇大作战(二)——规则界面
游戏规则界面: 从界面上可以看出,一共有三个按钮,两个切换按钮和一个退出按钮. 一共三张规则图片Sprite,我们通过设置其是否为Active来控制显示,其控制脚本代码如下: using System ...
- [Untiy]贪吃蛇大作战(一)——开始界面
前言: 刚学unity没多久吧(大概1个月多点),这是我自己做的除官网之外的第一个游戏demo,中间存在很多不足的地方,但是还是希望可以给需要的人提供一些思路和帮助,有问题的小伙伴可以找我一起探讨一起 ...
- Java实现贪吃蛇游戏【代码】
花了两个下午写了一个贪吃蛇小游戏,本人想写这游戏很长时间了.作为以前诺基亚手机上的经典游戏,贪吃蛇和俄罗斯方块一样,都曾经在我们的童年给我们带来了很多乐趣.世间万物斗转星移,诺基亚曾经作为手机业的龙头 ...
- 题解和总结——noip2019集训测试赛(一)贪吃蛇+字符串+都城
Problem A: 贪吃蛇 描述 Input Output Sample Input [样例输入1] 4 5 ##... ..1#@ 432#. ...#. [样例输出1] 4 [样例输入2] 4 ...
- c语言贪吃蛇详解-2.画出蛇
c语言贪吃蛇详解-2.画出蛇 前几天的实验室培训课后作业我布置了贪吃蛇,今天有时间就来写一下题解.我将分几步来教大家写一个贪吃蛇小游戏.由于大家c语言未学完,这个教程只涉及数组和函数等知识点. 蛇的身 ...
随机推荐
- 图像阈值_有cv2.threshold,cv2.adaptiveThreshold 等。
1.简单阈值 使用的函数:cv2.threshold (src, thresh, maxval, type) 注释: 与名字一样,这种方法非常简单.但像素值高于阈值时,我们给这个像素赋予一个新值(可能 ...
- 关于Linux下服务器MySQL的安装和搭建
一.检测是否已经安装Mysql 检测 # yum list installed | grep mysql //检查安装 # yum -y remove mysql-libs.x86_64 //卸载 / ...
- 彻底弄懂js中this指向(包含js绑定、优先级、面试题详解)
为什么要使用this 在javascript中,this可谓是无处不在,它可以用来指向某些元素.对象,在合适的地方使用this,能让我们减少无用代码的编写 var user = { name: & ...
- 形象谈JVM-第三章-即时编译器优化技术
即时编译器优化技术一览: 相信许多同学看完这个表格,脑子里面嗡嗡的,这些名字也是晦涩难懂,要实现这些优化的技术确实有比较大的难度,但是咱们只是学习,去理解这些技术,其实并不难,下面咱们直接开讲. 首先 ...
- 【pandas小技巧】--统计值作为新列
这次介绍的小技巧不是统计,而是把统计结果作为新列和原来的数据放在一起.pandas的各种统计功能之前已经介绍了不少,但是每次都是统计结果归统计结果,原始数据归原始数据,没有把它们合并在一个数据集中来观 ...
- python机器学习经典算法代码示例及思维导图(数学建模必备)
最近几天学习了机器学习经典算法,通过此次学习入门了机器学习,并将经典算法的代码实现并记录下来,方便后续查找与使用. 这次记录主要分为两部分:第一部分是机器学习思维导图,以框架的形式描述机器学习开发流程 ...
- P2024 [NOI2001] 食物链 || #576. 食物链【NOI2001】 (并查集)
空降锣鼓 空降OJ 题解: #include<bits/stdc++.h> using namespace std; int n,k; int d,x,y; int ans; int fa ...
- Elasticsearch之环境搭建
一.安装 elasticsearch -- 拉取镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:8.9.1 -- 创建 doc ...
- 小知识:OCI实例的私钥文件权限
在OCI上创建新的实例时,会提示你保存私钥用于连接,而且该界面不会再次显示,所以一定要保存好这个私钥. 实例创建完成后,当使用保存的私钥进行连接时,却发现由于私钥文件的权限问题无法连接,查看当前私钥文 ...
- 探秘公有IP地址与私有IP地址的区别及其在路由控制中的作用
引言 IP地址是互联网通信中至关重要的组成部分.虽然在前一章节我们讲解了IP一些基础知识,但在我们日常生活中,我们经常听到公有IP地址和私有IP地址这两个术语.那么,公有IP地址和私有IP地址有何区别 ...