HDU 4826 Labyrinth(DP解法)
Problem Description
度度熊是一只喜欢探险的熊,一次偶然落进了一个m*n矩阵的迷宫,该迷宫只能从矩阵左上角第一个方格开始走,只有走到右上角的第一个格子才算走出迷宫,每一次只能走一格,且只能向上向下向右走以前没有走过的格子,每一个格子中都有一些金币(或正或负,有可能遇到强盗拦路抢劫,度度熊身上金币可以为负,需要给强盗写欠条),度度熊刚开始时身上金币数为0,问度度熊走出迷宫时候身上最多有多少金币?
Input
输入的第一行是一个整数T(T < 200),表示共有T组数据。
每组数据的第一行输入两个正整数m,n(m<=100,n<=100)。接下来的m行,每行n个整数,分别代表相应格子中能得到金币的数量,每个整数都大于等于-100且小于等于100。Output
对于每组数据,首先需要输出单独一行”Case #?:”,其中问号处应填入当前的数据组数,组数从1开始计算。
每组测试数据输出一行,输出一个整数,代表根据最优的打法,你走到右上角时可以获得的最大金币数目。Sample Input
2
3 4
1 -1 1 0
2 -2 4 2
3 5 1 -90
2 2
1 1
1 1
Sample Output
Case #1:
18
Case #2:
4
这题一开始我用的是DFS,发现超时了,然后百度了一下,发现要用DP。
DP思路是这样的:
①从左向右走的时候
要求(i,j)的最大值,就需要先求出 (i,j-1)的最大值。
可以到( i , j-1 )格子的有0,1,2三个格子, (i,j-1) 的值与从何处过来有关
所以我们需要对比 从0,1,2过来(i,j-1)的情况。
我们用 dp[i][j][k] 记录位置 (i,j) 从 方向 k 过来的最大值(k=0,1,2)
即 dp[ i ][ j ][ 1 ] = max( dp[ i ][ j - 1 ][ 0 ] , dp[ i ][ j - 1 ][ 1 ] , dp[ i ][ j - 1 ][ 2 ] ) + money[ i ][ j ];
②从下向上
dp[ i ][ j ][ 2 ] = max( dp[ i + 1 ][ j ][ 1 ] , dp[ i + 1 ][ j ][ 2 ] ) + money[ i ][ j ];
③从上向下
dp[ i ][ j ][ 0 ] = max(dp[ i - 1 ][ j ][ 0 ] , dp[ i - 1 ][ j ][ 1 ] ) + money[ i ][ j ];
当然,我们还需要考虑一下边界问题。
上边界
dp[ 1 ][ j ][ 0 ] = - INF
下边界
dp[ m ][ j ][ 2 ] = - INF
我们也可以一开始就把dp[i][j][k]初始化为 -INF
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string.h>
#define INF 99999999
using namespace std;int money[101][101];
int dp[101][101][3];//i,j,k
//其中 k=0 从上过来 k=1 从左过来 k=2 从下过来
int max(int x, int y) {return x > y ? x : y;
}int main() {int T, m, n, c;int i, j, k;scanf("%d", &T);c = 1;while (c <= T) {scanf("%d %d", &m, &n);for (i = 1; i <= m; i++)for (j = 1; j <= n; j++)scanf("%d", &money[i][j]);memset(dp, -INF, sizeof(dp));//初始化dp[1][1][0] = dp[1][1][1] = dp[1][1][2] = money[1][1];for (i = 2; i <= m; i++)dp[i][1][0] = dp[i - 1][1][0] + money[i][1];for (j = 2; j <= n; j++) {for (i = 1; i <= m; i++)//从左向右dp[i][j][1] = max(max(dp[i][j - 1][0], dp[i][j - 1][1]), dp[i][j - 1][2]) + money[i][j];for (i = 2; i <= m; i++)//从上向下dp[i][j][0] = max(dp[i - 1][j][0], dp[i - 1][j][1]) + money[i][j];for (i = m - 1; i >= 1; i--)//从下向上dp[i][j][2] = max(dp[i + 1][j][1], dp[i + 1][j][2]) + money[i][j];}printf("Case #%d:\n", c);printf("%d\n", max(max(dp[1][n][0], dp[1][n][1]), dp[1][n][2]));c++;}return 0;
}
HDU 4826 Labyrinth(DP解法)相关推荐
- [poj 1014]Dividing的DFS解法解读和DP解法
转载来源: http://blog.csdn.net/lyy289065406/article/details/6661449 这道题比较特殊,用DFS也是对的,而且可以进行优化,即使直接n[i]-- ...
- hdu 1520 树形dp
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 #include<cstdio> #include<cstring> # ...
- hdu 4035 可能性DP 成都网络游戏
http://acm.hdu.edu.cn/showproblem.php?pid=4035 获得: 1.首先推断是不是树.事实上,所有的感觉身影,既看边数==算-1是不成立 2.有时候,我告诉孩子来 ...
- HDU 2836 (离散化DP+区间优化)
Reference:http://www.cnblogs.com/wuyiqi/archive/2012/03/28/2420916.html 题目链接: http://acm.hdu.edu.cn/ ...
- hdu 5568(dp+大数模拟)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5568 官方题解: #include <cstdio> #include <cstri ...
- hdu 5464(简单dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5464 解题思路: 由于p很小,而ai很大,所以先把ai%p,由于ai可能有负数,所以ai=(ai%p+ ...
- hdu 5433(bfs+dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5433 解题思路: dp[i][j][k]表示在(x,y)点,毅力为k时的最小体力.由于每个点可能会走多 ...
- HDU 2859 Phalanx (dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2859 给你一个n*n的矩阵,问你最大的对称度是多少(左下右上为对称线) dp[i][j]表示i行j列元 ...
- HDU中一些DP的题目分类
DP是难点,供自已以后系统学习. 1.Robberies 连接 :http://acm.hdu.edu.cn/showproblem.php?pid=2955 背包;第一次做的时候把概率当做 ...
最新文章
- 如何配置pom.xml用maven打包java工程
- Python 技术篇-用os库实现本地文件重命名实例演示
- 深度学习核心技术精讲100篇(二十九)-基于内容和上下文的音乐推荐
- HTML中常用知识点整理
- flock SUSE/RHEL
- Spring Cloud学习笔记-009
- java 处理时间的类_java 日期时间处理类
- 数据库设计的三大范式[学习笔记]
- 线程安全问题的本质详解: 原子性、有序性、可见性
- Dinic最大流(bzoj 2756: [SCOI2012]奇怪的游戏)
- IP地址的分类,五分类编制CIDR以及子网的划分和子网掩码
- 浅谈电力巡检机器人功能及特点
- 计算机专用英语词汇1695个词汇表
- 【数据压缩】H.264码流分析
- 域名注册绑定内网穿透项目部署
- format的几种用法
- usb xhci babble error问题解决
- python研究背景和意义_选题背景、目的及研究意义
- 程序员常用的工具网站
- 从从协方差的误差椭圆到PCA