[刷题笔记] Luogu P2196 挖地雷
Description
题目描述有点花哨,我们先来理解一下:
在一条数轴上,有\(n\)个点,每个点都有一个值\(a_i\),且给定连接点之间的\(m\)条路径,求一条路径使得经过的点值和最大
Solution
题意简化了比较明确,我们来将样例画一下:
(图中数字表示每个点地雷数量,弧线表示路径)
观察一下图,举个例子,以4号点结尾的路径最大值,有两种选择:
- 先从1号点到3号点,再从4号点到7号点
- 直接从1号点到4号点
显然我们会选择从方案1,因为此时的地雷是10+4+7是要优于方案2的。
同理,若以3号为结尾的路径最大值,由于只有一条路径,所以一定选它。(如果不选它则后边的选择一定不是最优的,就没必要继续下去,可以理解为记忆化搜索,满足了局部最优解,是dp的特征)
这时我们就找到了以\(i\)为结尾路径最大值之间的关系,具体一点,以\(i\)结尾的路径最大值 = 以和\(i\)有连接关系的点结尾路径最大值+\(i\)号点地雷数。
显然dp,上述即为状态转移,若令\(f_i\)为以\(i\)结尾路径最大值,则满足:
\(f_i = max(f_j)+a_i\)
(\(j\)为和\(i\)有连接关系的点,\(a[i]\)为\(i\)号点的地雷数)
需要注意\(j<i\),因为显然对于每次选择我们只能选择其前面的。
容易发现这样的状态转移借鉴了最长不下降子序列,这可以算是一类模型。
至于求最大地雷数,取dp数组的max就好啦!
此时,求路径上最大地雷数得解。
如何记录我们是如何选择的呢?
回想一下我们是如何dp的,对于每一个点我们都取了在它前边且有连接关系的点作为结尾的路径最大值,我们可以记录一下我们选择了从\(j\)到\(i\)的路线是最优的。同时为了求最大地雷数我们还对dp数组取max,只需要在每次取max的时候记录一下max是以哪个点为结尾的路径就好啦。
由于我们在前面已经记录了从\(j\)到\(i\)的路线是最优的,故dfs倒序输出即可。(如果文字很抽象见代码)
此时,问题得解,代码显然。
Code
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
#define N 1010
using namespace std;
int mapp[N][N];
int dp[N];
int a[N];
int n;
int p_last;
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
int path[N];
int maxn = -1;
int pos;
void dfs(int x)
{
if(path[x]) dfs(path[x]); //如果当前点还有前驱则继续搜
cout<<x<<" "; //倒叙输出
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<n;i++)
{
for(int j=i+1;j<=n;j++)
{
int k;
scanf("%d",&k);
if(k) mapp[j][i] = 1; //存图,有向图即可,具体原因见上文
}
}
dp[1] = a[1]; //dp边界
for(int i=1;i<=n;i++) dp[i] = a[i]; //初始化dp数组,因为每次我们都可以只选择本身
for(int i=2;i<=n;i++)
{
for(int j=1;j<i;j++)
{
if(dp[j]+a[i] > dp[i] && mapp[i][j]) //取以i为结尾路径最大值
{
dp[i] = dp[j] + a[i];
path[i] = j; //记录从j到i是最优的
}
if(dp[i] > maxn) maxn = dp[i],pos = i; //如果是max更新pos,pos即max是以pos结尾的
}
}
dfs(pos); //dfs输出路径
cout<<endl<<maxn<<endl;
return 0;
}
本文作者:SXqwq,转载请注明原文链接:https://www.cnblogs.com/SXqwq/p/17546105.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!