hdu5092 dp(递推)

题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5092

题意:给一个m*n的矩阵,找到一个纵向的"线"使得线上的和最小并输出这条线,线能向8个方向

延伸,要求找的是纵向的一条线(每一行各取一个点连成一线) ,输出路径,若有多条路径,输出最

靠右的。

注意!! 最靠右的意思是,从上往下最靠右的,是连成一条线上字典序是最大的!! 字典序!!!  eg(3,1,3)<(3,2,1)

好不容易自己想出来一道题 还因为字典序没搞懂一直WA。

字典序最大那么久要从下往上dp,找最小值里面最右面的,记录路径。这样就比较容易理解了。

具体见代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;

int mp[105][105];
int dp[105][105],path[105][105];
int d[105];
int m,n;

int main()
{
    int T;
    scanf("%d",&T);
    for(int p=1; p<=T; p++)
    {
        scanf("%d%d",&m,&n);
        for(int i=1; i<=m; i++)
            for(int j=1; j<=n; j++)
                scanf("%d",&mp[i][j]);

        memset(dp,0,sizeof(dp));
        memset(path,0,sizeof(path));

        for(int i=1; i<=n; i++)
            dp[m][i]=mp[m][i];
        for(int i=1; i<=n; i++)

            for(int i=m-1; i>=1; i--)
            {
                int maxx;
                for(int j=1; j<=n; j++)
                {
                    if(j==1)
                    {
                        maxx=dp[i+1][j],path[i][j]=j;
                        if(dp[i+1][j+1]<=dp[i+1][j]) maxx=dp[i+1][j+1],path[i][j]=j+1;
                    }

                    else if(j==n)
                    {
                        maxx=dp[i+1][j-1],path[i][j]=j-1;
                        if(dp[i+1][j]<=dp[i+1][j-1]) maxx=dp[i+1][j],path[i][j]=j;
                    }
                    else
                    {
                        maxx=dp[i+1][j-1],path[i][j]=j-1;
                        if(dp[i+1][j]<=maxx) maxx=dp[i+1][j],path[i][j]=j;
                        if(dp[i+1][j+1]<=maxx) maxx=dp[i+1][j+1],path[i][j]=j+1;
                    }
                    dp[i][j]=mp[i][j]+maxx;
                }
            }

        int minn=dp[1][1],k=1;
        for(int i=2; i<=n; i++)
            if(dp[1][i]<=minn)
                minn=dp[1][i],k=i;

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

        memset(d,0,sizeof(d));
        int pt=k,t=1;
        d[1]=k;
        for(int i=1; i<m; i++)
        {
            pt=path[i][pt];
            d[++t]=pt;
        }
        for(int i=1; i<t; i++)
            printf("%d ",d[i]);
        printf("%d\n",d[t]);
    }
    return 0;
}

 

posted @ 2016-10-16 11:36  a_clown_cz  阅读(402)  评论(0)    收藏  举报