多阶段决策问题——DAG(算法竞赛入门经典笔记)

本文介绍了如何运用DAG解决多阶段决策问题,如单向TSP和0-1背包问题。针对单向TSP问题,通过DAG上的动态规划求解最小数字和路径。0-1背包问题中,区分了物品无限和有限的情况,并给出状态转移方程及算法设计。递推法和记忆化搜索被用于优化解题过程。
摘要由CSDN通过智能技术生成

多阶段决策问题——DAG

本文为算法竞赛入门经典第九章第三节的笔记(刘汝佳. 算法竞赛入门经典.第2版[M]. 清华大学出版社, 2014.)
多阶段决策问题:每作一次决策就可以得到解的一部分,当所有决策做完之后,所有的解就“浮出水面”了。

多段图的最短路

单向TSP问题:

给定一个n*m的数字表格,找到一条从左到右的路径,使得上面的数字和最小。输出字典序最小的行号路径(每次可以从(i,j),走到(i,j+1),(i+1,j),(i-1,j)循环无限延伸没有边界)

思路:使用DAG上动态规划问题的基本思路。

  1. 读入数据
        for(int i=0;i<m;i++){
    
            for(int j=0;j<n;j++){
    
                cin >> tsp[i][j];
            }
        }
  1. 使用记忆化搜索的方法
int dp(int i,int j){
    
    int& ans=dtsp[i][j];
    if(ytsp[i][j])
        return ans;
    if(j >= n-1){
    

        ans=tsp[i][j];
        ytsp[i][j]=1;
        return ans;
    }
    int mmin,next3[3];
    next3[0]=(i-1+m)%m;
    next3[1]=i;
    next3[2]=(i+1)%m;
    sort(next3,next3+3);
    ans=min(tsp[i][j]+dp(next3[0],j+1),tsp[i][j]+dp(next3[1],j+1))+1;
    for(int ii=0;ii<3;ii++){
    
        if(tsp[i][j]+dp(next3[ii],j+1) < ans){
    
            ans=tsp[i][j]+dp(next3[ii],j+1);
            retsp[i][j]=next3[ii];
        }
    }

    ytsp[i][j]=1;
    return ans;
}
  1. 打印输出字典序最小的策略
int eend = min(dtsp[0][0],dtsp[1][0])+1;
        int cur;
        for(int i=0;i<m;i++){
    
            if(dtsp[i][0] < eend){
    
                eend=dtsp[i][0];
                cur=i;
            }
        }
        cout << cur+1 ;
        for(int i=0;i<n-1;i++){
    

            cur = retsp[cur][i];
            cout << " " << cur+1;
        }

完整程序:

#define LOCAL
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
//#include <stdio.h>
#include <cstdlib>
#include<time.h>
#include <ctype.h>
#include <sstream>
#include <assert.h>
#include <math.h>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#define MAXN 92

using namespace std;

int tsp[11][101];


int m,n;

int dtsp[11][101];//记录从该点出发的深度
int ytsp[11][101];//记录该点是否被运算过
int retsp[11][101];//路径的记录
int dp(int i,int j){
    
    int& ans=dtsp[
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值