每做一次决策就可以得到解得一部分,当做完所有决策做完之后,完整的解就浮出水面了。在回溯法中,每次决策对应给一个结点产生新的子树,而解的生成过程对应一颗解答树,结点的层数就是“下个待填充位置”cur
9.3.1多段图的最短路
多段图是一种特殊的DAG,其结点可以划分成若干个阶段,每个阶段只有上一个阶段所决定
例题:单向TSP
分析:
在这个题目中,每一列就是一个阶段,每个阶段有三种决策
多阶段决策的最优化问题往往可以通过用动态规划解决,其中,状态及其转移类似于回溯法中的解答树,解答树的中的“层数”,也就是递归函数中的“当前填充位置cur”,描述的是即将完成的决策序号,在动态规划中被称为阶段
有了前面的经验,不难设计出状态,设d(i,j)为从格子(i,j)出发到最后一列的最小开销,但是本题不仅要输出解,还要求字典序最小,这就需要在计算d(i,j)的同时记录“下一列的行号”的最小值
int ans=INF,first=0;
for(int j=n-1;j>=0;j--){
for(int i=0;i<m;i++){
if(j==n-1)
d[i][j]=a[i][j]; //边界
else{
int rows[3]={i,i-1,i+1};
if(i==0) rows[1]=m-1;
if(i==m-1) rows[2]=0;
sort(rows,rows+3); //重新排序,以便找到字典序最小
d[i][j]=INF;
for(int k=0;k<3;k++){
int v=d[rows[k]][j+1]+a[i][j];
if(v<d[i][j]) {d[i][j]=v;next[i][j]=rows[k]; }
}
}