UVA116 简单的多阶段DP

来源:互联网 发布:2016nba总决赛数据 编辑:程序博客网 时间:2024/05/19 03:27

题意

M行N列的矩阵,求从一边到另一边的最短路。矩阵的最顶端和最底端是相连的。

题解

从最后一列开始逆推,求最短路并记录下来。在记录最短路的过程中,如果某一列存在两个最优解的情况,选择字典序小的那个最优解。最后把记录下来的最短路输出即可。

注意事项

注意m行1列的情况,被这种情况坑了好久。。。。

代码

#include <iostream>#include<cstdio>#include<algorithm>#define INF 1e9using namespace std;int dp[20][110];int nex[20][110];int a[20][110];int main(){    int n,m;    while(scanf("%d%d",&n,&m)!=EOF){        for(int i=1;i<=n;i++){            for(int j=1;j<=m;j++){                scanf("%d",&a[i][j]);                dp[i][j]=INF;            }        }        int ans=INF,first=0;        for(int j=m;j>=1;j--){            for(int i=1;i<=n;i++){                if(j==m)                    dp[i][j]=a[i][j];                else{                    int k[3]={i,i+1,i-1};                    if(i==n)                        k[1]=1;                    if(i==1)                        k[2]=n;                    sort(k,k+3);                    for(int s=0;s<3;s++){                        int an=dp[k[s]][j+1]+a[i][j];                        if(an<dp[i][j]){                            dp[i][j]=an;                            nex[i][j]=k[s];                        }                    }                }                if(j==1&&dp[i][j]<ans){                    ans=dp[i][j];                    first=i;                }            }        }        int last=first;        printf("%d",first);        for(int i=1;i<=m-1;i++){            printf(" %d",nex[last][i]);            last=nex[last][i];        }        printf("\n%d\n",ans);    }    return 0;}
0 0
原创粉丝点击