zoukankan      html  css  js  c++  java
  • 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
    ", ++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(), " 
    "[i == m-1]);
                st.pop();
            }
        }
    
        return 0;
    }
  • 相关阅读:
    面试题27:二叉树的镜像
    面试题26:树的子结构
    面试题25:合并两个排序的链表
    面试题24:反转链表
    面试题23:链表中环的入口节点
    面试题22:链表中倒数第k个节点
    欧拉函数的使用
    C++ STL 全排列函数详解
    Ubuntu系统安装网易云音乐、搜狗输入法
    Ubuntu系统 安装谷歌 Chrome 浏览器
  • 原文地址:https://www.cnblogs.com/dishu/p/4517795.html
Copyright © 2011-2022 走看看