[SHOI2003]吃豆豆(dp+拓扑排序)
[SHOI2003]吃豆豆
蒟蒻的 第一篇blog,请各位大犇多多指正
题目描述
两个PACMAN吃豆豆。一开始的时候,PACMAN都在坐标原点的左下方,豆豆都在右上方。PACMAN走到豆豆处就会吃掉它。PACMAN行走的路线很奇怪,只能向右走或者向上走,他们行走的路线不可以相交。 请你帮这两个PACMAN计算一下,他们俩加起来最多能吃掉多少豆豆。
输入格式
第一行为一个整数N,表示豆豆的数目。 接下来 N 行,每行一对正整数,表示第i个豆豆的坐标。任意两个豆豆的坐标都不会重合。
输出格式
仅有一行包含一个整数,即两个PACMAN加起来最多能吃掉的豆豆数量
输入输出样例
//输入
8
8 1
1 5
5 7
2 2
7 8
4 6
3 3
6 4
//输出
7
说明/提示
N < = 2000
分析
因为本题数据较大,暴搜的方法完全不可能实现 (只要你不怕TLE ),所以尝试使用动态规划+拓扑排序的方法。
状态转移方程可以轻易推出(其实是代码啦):
void dp(int x, int y) {for (int i = head[x]; i; i = eg[i].next) {int v = eg[i].v, u = y;if (id[v] > id[u]) std::swap(u, v);if (u != v) f[v][u] = std::max(f[v][u], f[x][y]+1);else f[v][u] = std::max(f[v][u], f[x][y]);}
}
但就是这样你会发现你还是没法AC
以下是题目中可能出现的几个问题:
怎样处理不相交的问题
如图所示,相交的条件在本题中没有起到任何作用。
如何建图
把每个可以互相达到的边都连起来跑会TLE,根据传递性,若i–>j,j–>k,则i–>k,且本题这样做还可以多吃一枚豆子,如图:上代码:
#include <cstdio> #include <queue> #include <algorithm> const int N = 1e5 + 7, M = 2007; struct Node {int x, y;bool operator < (const Node &b)//重载运算符 {return x<b.x || x==b.x&&y<b.y;} } nd[N]; struct Edge//建图 {int u, v, next; } eg[N<<2]; int head[N], n, in[N], id[N], tid[N], cnt, f[M][M]; inline void addEdge(int u, int v) {static int cnt = 1;eg[++cnt] = Edge { u, v, head[u] };head[u] = cnt; } void tpSort(int s)//拓扑排序 {std::queue<int> que;que.push(s);while(que.size()) {int u = que.front(); que.pop();id[u] = ++cnt; tid[cnt] = u;for (int i = head[u]; i; i = eg[i].next)if (--in[eg[i].v] == 0)que.push(eg[i].v);} } void dp(int x, int y)//动态规划 {for (int i = head[x]; i; i = eg[i].next) {int v = eg[i].v, u = y;if (id[v] > id[u]) std::swap(u, v);if (u != v) f[v][u] = std::max(f[v][u], f[x][y]+1);else f[v][u] = std::max(f[v][u], f[x][y]);} } int main() {scanf("%d", &n);for (int i = 1; i <= n; ++i)scanf("%d%d", &nd[i].x, &nd[i].y);std::sort(nd+1, nd+n+1);for (int i = 1; i <= n; ++i) {int mx = 2e9;for (int j = i+1; j <= n; ++j)if (nd[i].y<=nd[j].y && nd[j].y<mx)mx = nd[j].y, ++in[j], addEdge(i, j);}int s = 0, t = n + 1.//为了最终存答案新设的两个点;for (int i = 1; i <= n; ++i)addEdge(s, i), ++in[i], addEdge(i, t), ++in[t];tpSort(s);for (int i = 1; i <= cnt; ++i)for (int j = i; j <= cnt; ++j)dp(tid[i], tid[j]);printf("%d\n", f[t][t]-1);return 0; }
更多细节,希望对您有帮助
[SHOI2003]吃豆豆(dp+拓扑排序)相关推荐
- SHOI2003吃豆豆
原题链接(对,我就是懒得抄题了 ) 第一眼看过去, dp ,再一看, 2个peaman, 多开几维而已, 也还好,但看一眼数据范围,没给x和y的取值, 这就很烦人了, 如果开x和y的二维数组存是有点会 ...
- BZOJ4011:[HNOI2015]落忆枫音(DP,拓扑排序)
Description 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出这样一个问题. 「相信吧.不然我们是什么,一团肉吗?要不是有灵魂--我们也 ...
- [SHOI2003]吃豆豆
题目描述 两个PACMAN吃豆豆.一开始的时候,PACMAN都在坐标原点的左下方,豆豆都在右上方.PACMAN走到豆豆处就会吃掉它.PACMAN行走的路线很奇怪,只能向右走或者向上走,他们行走的路线不 ...
- 洛谷P3953 逛公园(dp 拓扑排序)
题意 题目链接 Sol 去年考NOIP的时候我好像连最短路计数都不会啊qwq.. 首先不难想到一个思路,\(f[i][j]\)表示到第\(i\)个节点,与最短路之差长度为\(j\)的路径的方案数 首先 ...
- 2019 ICPC Asia Nanjing Regional C.Digital Path(拓扑排序递推DP)
整理的算法模板合集: ACM模板 题目传送门 三段题面,只有第三段是有用的-前两段又长单词又难懂,就是在讲故事...不过针对四种情况给出四个图帮助我们理解题意是真的赞,可能出题人怕我们看不懂吧(第一句 ...
- [NOIP2017]逛公园 最短路+拓扑排序+dp
题目描述 给出一张 $n$ 个点 $m$ 条边的有向图,边权为非负整数.求满足路径长度小于等于 $1$ 到 $n$ 最短路 $+k$ 的 $1$ 到 $n$ 的路径条数模 $p$ ,如果有无数条则输出 ...
- Wannafly挑战赛22 B 字符路径 ( 拓扑排序+dp )
链接:https://ac.nowcoder.com/acm/contest/160/B 来源:牛客网 题目描述 给一个含n个点m条边的有向无环图(允许重边,点用1到n的整数表示),每条边上有一个字符 ...
- 【NOIP2017】逛公园【最短路DAG】【dp】【拓扑排序】
题意:给一张帯权有向图,求 111 到 nnn 长度不超过最短路长度 +k+k+k 的路径条数 模 PPP.有无数条输出 −1-1−1 . n≤105,m≤2×105,k≤50n\leq 10^5,m ...
- [多校联考-西南大学附中]切面包(线段树/概率与期望)+ Slow Path Finding Algorithm(拓扑排序/DP)+ 分数转化(数论)
文章目录 T1:分数转换 题目 题解 代码实现 T2:Slow Path Finding Algorithm 题目 题解 代码实现 T3:切面包 题目 题解 代码实现 T1:分数转换 题目 Time ...
最新文章
- [转载].NET中高效能的socket编程
- 一家专业做SEO的公司介绍给大家|利槿网络
- 启动elasticsearch命令_快速安装ElasticSearch
- bat查看java进程 过滤_通过查找.BAT中使用的端口来终止进程
- 关于oracle date类型值0000-0-0的分析
- CASE_04 基于FPGA的电梯控制器
- webug3.0下载环境搭建使用
- 【Unity】Update()和FixedUpdate()
- java 增长因子_Java ArrayList的扩容因子为什么是1.5?
- el-option传两个值_俗话说买房看地段,买窗看K值:如何区分K值、U值和R值
- python里怎么读取文件-python如何读取文件的数据
- Java自学如何找工作?
- 50漂亮的后台管理界面模板
- s3c2440的时钟体系
- 两种有效提高win10电脑开机速度的方法
- html修改word页边距,Word怎么只修改一页的页边距,而不影响同一文件中的其他页?...
- 树莓派人体感应警报(python)HC-SR501红外人体感应
- 数仓建模—数仓架构发展史(02)
- 高斯判别分析(GDA)Python代码
- 四针角oled屏连接arduino_ESP8266连接OLED显示屏并显示位图图像