数塔问题练习5294_挖地雷
来源:互联网 发布:windows 10 pro iso 编辑:程序博客网 时间:2024/05/18 09:22
/*Name: 5294_挖地雷Copyright: Author: Date: 06-08-17 21:29Description:5294_挖地雷 时间限制: 1 s 空间限制: 1000 KB 题目等级 : 黄金 Gold 题解题目描述 Description在一个地图上有N个地窖(N<=20),每个地窖中埋有一定数量的地雷。同时,给出地窖之间的连接路径。当地窖及其连接的数据给出之后,某人可以从第一个地窖开始挖地雷,然后可以沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。设计一个挖地雷的方案,使某人能挖到最多的地雷。输入描述 Input Description第1行只有一个数字,表示地窖的个数N。第2行有N个数,分别表示每个地窖中的地雷个数。第3行至第N+1行表示地窖之间的连接情况:第3行有n-1个数(0或1),表示第一个地窖至第2个、第3个、…、第n个地窖有否路径连接。如第3行为1 1 0 0 0 … 0,则表示第1个地窖至第2个地窖有路径,至第3个地窖有路径,至第4个地窖、第5个、…、第n个地窖没有路径。第4行有n-2个数,表示第二个地窖至第3个、第4个、…、第n个地窖有否路径连接。… …第n+1行有1个数,表示第n-1个地窖至第n个地窖有否路径连接。(为0表示没有路径,为1表示有路径)。输出描述 Output Description第一行表示挖得最多地雷时的挖地雷的顺序,各地窖序号间以一个空格分隔,不得有多余的空格。第二行只有一个数,表示能挖到的最多地雷数。样例输入 Sample Input510 8 4 7 61 1 1 00 0 01 11样例输出 Sample Output1 3 4 527*/#include<iostream> #include<cstring> using namespace std; const int MAX = 20; int map[MAX+1][MAX+1]; int W[MAX+1]; //记录每个地窖中的地雷个数int F[MAX+1]; //记录从第i个地窖开始最多可以挖出的地雷数 int F2[MAX+1]; //记录从第i个地窖开始最多可以挖出的地雷数int next[MAX+1]; //记录地窖i的后续地窖编号 int DP(int n); //动态规划(逆推法)void PrintPath(int pos); //输出最佳路径int DP_2(int n, int i); //备忘录算法 int main() { int n; cin >> n; for (int i=1; i<=n; i++) { cin >> W[i]; } for (int i=1; i<n; i++) { for (int j=i+1; j<=n; j++) { cin >> map[i][j]; } } //动态规划算法 int pos = DP(n); PrintPath(pos); //输出最佳路径 cout << F[pos] << endl; //备忘录算法pos = n; F2[n] = W[n];for (int i=1; i<n; i++)//因为入口有多个,必须一一计算 { if (F2[pos] < DP_2(n, i)) pos = i; } PrintPath(pos); //输出最佳路径 cout << F2[pos] << endl; return 0; } int DP(int n) //动态规划(逆推法),返回最佳起点下标 { F[n] = W[n];for (int i=n-1; i>0; i--){for (int j=i+1; j<=n; j++)//寻找最佳路径 {if (map[i][j] && F[i] < F[j]){F[i] = F[j];next[i] = j;}}F[i] += W[i];} int m = n;for (int i=1; i<n; i++)//找到最佳起点下标 { if (F[i] > F[m]) m = i; } return m;} int DP_2(int n, int i) //备忘录算法 { if (F2[i] != 0) return F2[i]; if (i == n) {F2[i] = W[n];}else{int t, m = 0;for (int j=i+1; j<=n; j++){if (map[i][j]){t = DP_2(n, j);if (m < t){m = t;next[i] = j;}}}F2[i] = m + W[i];} return F2[i];} void PrintPath(int pos) //输出最佳路径 { cout << pos; for(pos=next[pos]; pos!=0; pos=next[pos]) {cout << " " << pos;} cout << endl;}
阅读全文
0 0
- 数塔问题练习5294_挖地雷
- 14_扫雷游戏地雷数计算
- 练习赛6.2.挖地雷
- 挖地雷问题_DP
- 挖地雷问题
- 挖地雷问题 dfs
- 挖地雷问题(DAG最长路)
- 挖地雷问题 单向 动态规划
- 挖地雷
- 挖地雷
- 挖地雷
- 挖地雷
- 挖地雷
- 挖地雷
- 挖地雷
- 挖地雷
- 挖地雷
- 挖地雷
- 学习jdbc(一周总结)
- 为什么ARM的启动代码是汇编?
- HDOJ 1203 I NEED A OFFER!(01背包)
- 空气动力与电机力学
- Socket客户端与服务端通信私聊
- 数塔问题练习5294_挖地雷
- 工厂模式的几种形态
- 2017年8月6日 星期日
- 运算符详解
- deepin安装mysql/navicat
- 寻找旋转排序数组中的最小值
- C#静态方法和非静态方法
- DOS命令
- Java IO--File完全解析