UVa 单向TSP (多短图的最短路)多阶段决策问题 dp

紫书270例题

给一个m行n列(m<=10,n<=100)的整数矩阵,从第一列任何一个位置出发每次往右,右上,或者右下走一格,最终到达最后一列。要求进过的整数之和最小,整个矩阵是环形的,级第一行的上一行是最后一行,最后一行的下一行是第一行。输出路径上每列的行号。多解时输出字典序最小的。

设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;}  //第0行上面是第m-1行
            if(i==m-1){rows[2]=0;} //第m-1行下面是第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];}
            }
        }
        if(j==0&&d[i][j]<ans){ans=d[i][j];first=i;}
    }
}
printf("%d",first+1); //输出第一列
for(int i=next[first][0],j=1;j<n;i=next[i][j],j++)
    printf(" %d",i+1); //输出其他列
printf("\n%d\n",ans);
}
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值