#include <iostream> #include <stack> using namespace std; int boomNum[1000]; bool isAccess[100][100];//[i][j]=true 表示 地窖i、j间是连接的 int m[1000];//表示从第i个地窖开始挖的最多地雷数 int main() { int n;//n个地窖 cin >> n; for (int i = 1; i <= n; i++) { cin >> boomNum[i]; //输入每个地窖有多少个雷 } int start = -1, end = -1; //填m表 初始化 输入若干行 最后一行00表示结束 while (!(start == 0 && end == 0)) { cin >> start >> end; isAccess[start][end] = true; } //从最大的num开始 //初始化 int max = -1; m[n] = boomNum[n];//固定末尾 int way[1000];//记录后继 way[i] 表示i的后继 int k = 0;//记录后继 //动态方程 for (int i = n - 1; i >= 1; i--) { //找谁和i相连 max = 0;//先初始化max k = 0; for (int j = i + 1; j <= n; j++) { //如果i 和 j 相连 尝试更新m[i] if (isAccess[i][j] && m[j] > max) { max = m[j]; k = j; } } m[i] = max + boomNum[i]; way[i] = k;//更新后继 记录路径 } max = -1; int max_i; //找出最大 for (int i = 1; i < n; i++) { //cout << way[i]; if (m[i] > max) { max = m[i]; max_i = i; } } //输出路径 cout << max_i; int t = max_i; while (way[t] > 0) { cout << "-" << way[t]; t = way[t]; } cout << endl; cout << max; }
这题突破口在题目设置 “并规定路径都是单向的,且保证都是小序号地窖指向大序号地窖” ,那么最大的那个地窖不指向任何地窖,则可以固定最大号的那个地窖的d,从大往小递推。
设d[i]为从i号地窖开始挖最大的地雷数,默认值为a[i]
令a[i] 为第i号地窖的地雷数
递归方程 : d[i] = max { d[j] + a[i] | i 与 j 之间相连} (i : 从大到小)
设way[i] 为i号地窖的后继地窖,默认为-1
way[i] = { j | i 与 j 相连 并且 d[j] + a[i] 取得最大 }
原文:https://www.cnblogs.com/likeghee/p/11748044.html