首页 > 其他 > 详细

动态规划 挖地雷

时间:2019-10-27 17:52:44      阅读:161      评论:0      收藏:0      [点我收藏+]
#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

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!