1262:【例9.6】挖地雷
题目链接
题目:
【题目描述】
在一个地图上有n个地窖(n≤200),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径,并规定路径都是单向的,且保证都是小序号地窖指向大序号地窖,也不存在可以从一个地窖出发经过若干地窖后又回到原来地窖的路径。某人可以从任意一处开始挖地雷,然后沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使他能挖到最多的地雷。
【输入】
第一行:地窖的个数;
第二行:为依次每个地窖地雷的个数;
下面若干行:
xiyi //表示从xi可到yi,xi<yi。
最后一行为"00"表示结束。
【输出】
k1−k2−…−kv //挖地雷的顺序
挖到最多的雷。
【输入样例】
6
5 10 20 5 4 5
1 2
1 4
2 4
3 4
4 5
4 6
5 6
0 0
【输出样例】
3-4-5-6
34
思路:
要求:挖到的地雷值最大-最值问题 ,路径必须保证是通路 ,可以从任一一处开始挖 (重叠子问题、无后效性都满足,所以用动态规划)
-
首先确定一下状态:
- 从前往后找地雷还是从后往前找-都需要判断路径,所以设置一个邻接矩阵rl[n] [n], 需要dp[n]存储包括挖到当前地雷时所有的(挖到之前/之后(从前往后挖)的)地雷最大值
- 要输出顺序,所以需要得到一个序列b[n],要得到b[n]还需要知道挖到某个地窖时,前/后一个(从前往后挖)地窖得到位置,即一个关系数组pre[n]/post[n]。
- 要清晰拿到b[n],还需要一个maxk来存放最开始的地雷位置/最后一个地雷位置(从前往后挖,回溯)
-
确定选择/方程:
- 挖到某个地窖,就选择所在前面/后面有通路的紧挨着的地窖最值+目前的地窖中地雷数目 即 max(dp[rl[i] [j]]+v[i],dp[i])
-
边界条件:
- 当没有通路时dp[i]值就是当前地窖数
- 求最值时,maxn!!!一定要初始化 ,最多为0
参考代码1
#include <bits/stdc++.h>
#define MAXN 205
using namespace std;
int a[MAXN][MAXN],dp[MAXN],pre[MAXN] ;//均初始化为0
int main(){
int n ,maxn=0,maxk,v[MAXN],b[MAXN]