uva116

来源:互联网 发布:司法考试培训班 知乎 编辑:程序博客网 时间:2024/06/06 01:39

题目大意:

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


题目分析:

每一列就是一个阶段,每个阶段都有3种决策:直行,右上和右下。在状态转移时按照字典序依次转移是否最后得到的路径即为字典序最小的路径?


代码:

#include <vector>#include <stdio.h>#include <iostream>using namespace std;const int maxn=200;const int INF=0x3f3f3f3f;int dp[maxn][maxn],Map[maxn][maxn];struct Coor{    int row,col;};Coor coor;vector<Coor>path[maxn][maxn];void print_map(int n,int m){    for(int i=0;i<n;i++){        for(int j=0;j<m;j++){            cout<<Map[i][j]<<" ";        }        cout<<endl;    }    cout<<endl;}void print_dp(int n,int m){    for(int i=0;i<n;i++){        for(int j=0;j<m;j++){            cout<<dp[i][j]<<" ";        }        cout<<endl;    }    cout<<endl;}void print_path(int row,int col,int m){    while(col!=m-1)    {        cout<<row+1<<" ";        int minrow=INF,temprow,tempcol;        for(int i=0;i<(int)path[row][col].size();i++){            if(minrow>path[row][col][i].row){                minrow=path[row][col][i].row;                temprow=minrow,tempcol=path[row][col][i].col;            }        }        row=temprow,col=tempcol;    }    cout<<row+1<<endl;    //cout<<endl;}int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int n,m;    while(cin>>n>>m)    {        coor.row=-1;coor.col=-1;        for(int i=0;i<=n+1;i++){            for(int j=0;j<=m+1;j++){                dp[i][j]=INF;                path[i][j].clear();            }        }        for(int i=0;i<n;i++){            for(int j=0;j<m;j++){                cin>>Map[i][j];            }        }        //print_map(n,m);        for(int i=m-1;i>=0;i--){            for(int j=0;j<n;j++){                if(i==m-1){                    dp[j][i]=Map[j][i];                } else {                    int up=dp[(j-1+n)%n][i+1]+Map[j][i];                    int r=dp[j][i+1]+Map[j][i];                    int down=dp[(j+1)%n][i+1]+Map[j][i];                    int minrow=INF;                    int MIN=min(min(up,r),down);                    dp[j][i]=MIN;                    if(up==MIN) minrow=min(minrow,(j-1+n)%n);                    if(r==MIN)  minrow=min(minrow,j);                    if(down==MIN)   minrow=min(minrow,(j+1)%n);                    coor.row=minrow;coor.col=i+1;                    path[j][i].push_back(coor);                }            }        }        //print_dp(n,m);        int pos,mincost=INF;        for(int i=0;i<n;i++){            if(mincost>dp[i][0]){                pos=i;                mincost=dp[i][0];            }        }        print_path(pos,0,m);        cout<<mincost<<endl;    }    return 0;}


原创粉丝点击