HDU 5092

http://acm.hdu.edu.cn/showproblem.php?pid=5092

卡读题,实质是每行取一个点,从上到下找一条路径权值和最小,点可以到达的地方是周围八个格子

类似数塔的dp,需要记录路径,当前行由上一行顶上的三个格子转移而来

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#include <stack>

using namespace std;
int n,m;
int a[105][105],dp[105][105],pre[105][105];
int dx[]={-1,-1,-1};
int dy[]={0,1,-1};

struct node{
    int x,y;
};

int main(){
    int T;
    scanf("%d",&T);
    for(int cas=1;cas<=T;cas++){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                scanf("%d",&a[i][j]);
            }
        }
        for(int i=0;i<105;i++)
            for(int j=0;j<105;j++)
                dp[i][j]=0xfffffff;
        for(int i=1;i<=m;i++)
            dp[1][i]=a[1][i];
        memset(pre,-1,sizeof(pre));
        for(int i=2;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(j-1>=1 && j+1<=m){
                    //dp[i][j]=min(dp[i][j],a[i][j]+min(dp[i-1][j],min(dp[i-1][j-1],dp[i-1][j+1])));
                    int t=min(dp[i-1][j],min(dp[i-1][j-1],dp[i-1][j+1]));
                    if(a[i][j]+t<dp[i][j]){
                        dp[i][j]=a[i][j]+t;
                        if(dp[i-1][j+1]<=dp[i-1][j-1] && dp[i-1][j+1]<=dp[i-1][j])
                            pre[i][j]=1;
                        else if(dp[i-1][j]<=dp[i-1][j-1] && dp[i-1][j]<=dp[i-1][j+1])
                            pre[i][j]=0;
                        else pre[i][j]=2;
                    }
                }
                else if(j-1>=1){
                    //dp[i][j]=min(dp[i][j],a[i][j]+min(dp[i-1][j],dp[i-1][j-1]));
                    int t=min(dp[i-1][j],dp[i-1][j-1]);
                    if(a[i][j]+t<dp[i][j]){
                        dp[i][j]=a[i][j]+t;
                        if(dp[i-1][j]<=dp[i-1][j-1])
                            pre[i][j]=0;
                        else pre[i][j]=2;
                    }
                }
                else if(j+1<=m){
                    //dp[i][j]=min(dp[i][j],a[i][j]+min(dp[i-1][j],dp[i-1][j+1]));
                    int t=min(dp[i-1][j],dp[i-1][j+1]);
                    if(a[i][j]+t<dp[i][j]){
                        dp[i][j]=a[i][j]+t;
                        if(dp[i-1][j+1]<=dp[i-1][j])
                            pre[i][j]=1;
                        else pre[i][j]=0;
                    }
                }
            }
        }
        int ans=0xfffffff;
        int res;
        for(int i=1;i<=m;i++){
            //ans=min(ans,dp[n][i]);
            if(ans>=dp[n][i]){
                ans=dp[n][i];
                res=i;
            }
        }
        printf("Case %d\n",cas);
        stack <node> s;
        node st;
        st.x=n;st.y=res;
        s.push(st);
        while(1){
            if(st.x==1)break;
            int xx=st.x+dx[pre[st.x][st.y]];
            int yy=st.y+dy[pre[st.x][st.y]];
            st.x=xx;st.y=yy;
            s.push(st);
        }
        for(int i=1;i<=n;i++){
            if(i==1)printf("%d",s.top().y);
            else printf(" %d",s.top().y);
            s.pop();
        }
        putchar(‘\n‘);
    }
    return 0;
}

时间: 2024-10-08 14:37:21

HDU 5092的相关文章

hdu 5092 Seam Carving dp+记录路径

Seam Carving Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 605    Accepted Submission(s): 253 Problem Description Fish likes to take photo with his friends. Several days ago, he found that so

hdu 5092 Seam Carving 简单DP ”水一炮试试“大法

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5092 非常卡读题 题目中说可以八个方向地走,完全没有提及是从上往下的 需要从样例中猜测”可能只是从上往下“,然后根据现场的过题情况决定要不要水一发试试 对于”水一炮试试“,感觉一般适用于: 1.本题的其他做法未果/很难写,其他的题目没法出 2.码的成本不会很高 3.心态上,得之我幸,失之我命 (水不过的时候,再检查一下水的姿势有没有什么不妥,如果还是不行,就要勇敢地.果断地走出过不了题的不开心-)

HDU 5092 DP

DP水题 求从上到下走完,使所取得权值最小,并输出路径,若有多个满足,则输出靠右的 #include "stdio.h" #include "string.h" int inf=0x3f3f3f3f; struct node { int x,y; }dp[110][110]; int main() { int Case,ii,i,j,n,m,ans; int a[110][110]; scanf("%d",&Case); for (ii=

hdu 5092 Seam Carving (简单数塔DP,题没读懂,,不过可以分析样例)

题意: 给一个m*n的矩阵,每格上有一个数. 找从第1行到第m行的一条路径,使得这条路径上的数之和最小. 路径必须满足相邻两行所选的两个数的纵坐标相邻(即一个格子必须是另一个格子的周围八个格子中的一个) 输出每一行取的数的列值.  若有多个答案,则路径要求尽量靠右. 思路: 简单数塔DP.题比较不好读,不过可以分析样例. 代码: int T,m,n; int a[105][105], f[105][105]; int path[105]; int main(){ cin>>T; rep(t,1

hdu 5092 Seam Carving

这道题 我没看出来 他只可以往下走,我看到的 8-connected :所以今天写一下如果是 8-connected 怎么解: 其实说白了这个就是从上到下走一条线到达最后一行的距离最小: 从Map[a][b] 到Map[a][b+1] 的距离是Map[a][b+1] 以此类推:建图即可: 然后在加一个点0,和n+m+1 点这样在建立一下从  0 点到第一行的边,和最后一行到(n+m+1) 的边 求一个从0 到(n+m+1) 的最短路径就好了, 怎么维护最右侧?:  Dijkstra  有 队列优

hdu 5092 Seam Carving(DP+记录路径)

Seam Carving Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 119    Accepted Submission(s): 69 Problem Description Fish likes to take photo with his friends. Several days ago, he found that som

LA 5092 &amp;&amp; hdu 3723 Delta Wave (卡特兰数)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=3723 and http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20568 题意:有种折线每向右延伸一个单位长度,高度要么不变,要么加1,要么减1.而且任何时刻高度不能低于0.求这种折线最终高度为0的情况总数. 分析:由于任何时刻斜向上的线不小于斜向下的线的数目,而且最终相等,,,,,卡特兰数模型.卡特兰数资料 若有i条斜向上的线,那

(hdu step 1.3.1)FatMouse&#39; Trade(在收入需要一定的付出的情况下求最大收入)

题目: FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5092 Accepted Submission(s): 1530   Problem Description FatMouse prepared M pounds of cat food, ready to trade with the cats gua

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;