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

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

 

非常卡读题

题目中说可以八个方向地走,完全没有提及是从上往下的

需要从样例中猜测”可能只是从上往下“,然后根据现场的过题情况决定要不要水一发试试

 

对于”水一炮试试“,感觉一般适用于:

1.本题的其他做法未果/很难写,其他的题目没法出

2.码的成本不会很高

3.心态上,得之我幸,失之我命

(水不过的时候,再检查一下水的姿势有没有什么不妥,如果还是不行,就要勇敢地、果断地走出过不了题的不开心~)

 

所以真正的题意是

只能从上往下走,8方向相邻

求权值和最小的路径 输出路径

如果有多条路径同时满足则输出最右的一条

 

教科书例题级别的DP

 

#include <cstring>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <stack>
#include <vector>
#include <queue>
#include <map>
#include <set>

using namespace std;

const int maxn = 110;
const int INF = 0x7fffffff;

int a[maxn][maxn];
int dp[maxn][maxn];
int pre[maxn][maxn];

int main()
{
    //freopen("in.txt", "r", stdin);

    int T;
    scanf("%d", &T);
    int kase = 0;
    while(T--)
    {
        printf("Case %d\n", ++kase);

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

        for(int i = 1; i <= m; i++)
            for(int j = 1; j <= n; j++)
                scanf("%d", &a[i][j]);

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

        for(int j = 1; j <= n; j++)
            dp[1][j] = a[1][j];

        for(int i = 2; i <= m; i++)
        {
            for(int j = 1; j <= n; j++)
            {
                if(dp[i-1][j-1] < dp[i-1][j] && dp[i-1][j-1] < dp[i-1][j+1]) //必须要严格小于才选最左边
                {
                    dp[i][j] = dp[i-1][j-1] + a[i][j];
                    pre[i][j] = j-1;
                }
                else if(dp[i-1][j] < dp[i-1][j+1])
                {
                    dp[i][j] = dp[i-1][j] + a[i][j];
                    pre[i][j] = j;
                }
                else
                {
                    dp[i][j] = dp[i-1][j+1] + a[i][j];
                    pre[i][j] = j+1;
                }
            }
        }

        int minloc = 0;
        for(int i = 1; i <= n; i++)
            if(dp[m][i] <= dp[m][minloc])
                minloc = i;

        stack<int> st;
        for(int i = m; i >= 1; i--)
        {
            st.push(minloc);
            if(i != 1)
                minloc = pre[i][minloc];
        }

        for(int i = 0; i < m; i++)
        {
            printf("%d%c", st.top(), " \n"[i == m-1]);
            st.pop();
        }
    }

    return 0;
}

 

posted @ 2015-05-20 17:51  地鼠地鼠  阅读(213)  评论(0编辑  收藏  举报