HDU 5092 Seam Carving (简单dp+保存路径)

题意,给一个数字矩阵,要求从上往下的一条路径,使这条路径上数字之和最小,如有多条输出最靠右的一条。

当时做的时候题意迷了。

思路:dp+记录路径,

 具体处理:加冗余点减少代码量

#include<cstdio>

#include<cstring>

#include<vector>

using namespace std;

const int maxn = 100;

int g[maxn+2][maxn];

int d[maxn+2][maxn];

int pa[maxn+2][maxn];

int m,n;

const int INF = 1e9;

void init(){

    memset(*pa,-1,sizeof(*pa));

    for(int i = 0; i < maxn; i++)

        d[i][0] = INF;

}



vector<int> ans;

void print_ans(int s){

    ans.clear();

    ans.push_back(s);

    for(int i = m-1; i > 0; i--){

        s = pa[i][s];

        ans.push_back(s);

    }

    for(int i = ans.size()-1; i > 0 ;i--){

        printf("%d ",ans[i]);

    }

    printf("%d\n",ans[0]);

}



void work()

{

    for(int i = 1; i <= n; i++ )

        d[0][i] = g[0][i];

    for(int i = 0; i < m; i++){

        d[i][n+1] = INF;

    }

    for(int i = 1; i < m ;i++){

        for(int j = 1; j <= n ; ++j ){

            int Min = -1;

            for(int k = 0; k <=1; k++){

                if(d[i-1][j+k] <= d[i-1][j+Min]){

                    Min = k;

                }

            }

            pa[i][j] = j+Min;

            d[i][j] = d[i-1][j+Min] + g[i][j];

        }

    }

    int Min = 0;

    for(int i = 1; i <= n; i++ ){

        if(d[m-1][Min] >= d[m-1][i]){

            Min = i;

        }

    }

    print_ans(Min);

}



int main()

{

    int T;

    init();

    scanf("%d",&T);

    for(int i = 1; i <= T; i++){

        printf("Case %d\n",i);

        scanf("%d%d",&m,&n);

        for(int i = 0; i < m; i++)

            for(int j = 1; j <= n; j++)

                scanf("%d",g[i]+j);

        work();

    }

    return 0;

}

 

你可能感兴趣的:(seam)