[DP/记忆化搜索] HDU 1078
来源:互联网 发布:仁霸玻璃优化软件 编辑:程序博客网 时间:2024/06/07 20:28
题意
给定一幅图,每个点有一定权值,现在有一只老鼠在起始点(0,0),他能水平或者垂直移动1~k格之后,停在某点并获得权值,而且每次移动后所在的点,都要比刚离开的那个点的权值更大,求最多能获得多少权值。
思路
开始用bottom - up 的 dp做的,当前的最小是来自四个方向的最小,但出现的问题就是因为是按照从左到右,从上到下的顺序访问的,每个点可能更新的时候周围不是最优,解决的方法是按照值的大小顺序访问,就能保证正确。
很多人用的是记忆化搜索,也就是top-down(memoized)的dp,第一次发现这两个的区别,memoized是从源开始找到四周不会再更新的点,再返回向上。搜索的顺序直接就保证了最优。
记忆化搜索还是搜索,从一条路通到底那种,通许多次而已,而dp只是找每个i,j所代表的最大的权值,他的顺序是死的,只是从两个for循环按部就班的找,所以他的路径是死的,一开始这题跟hdu2571一样,那题只能是往有往下走,不能回头,而这题,是四个方向都可以走,是一个“搜索”,所以要用记忆化搜索。
记忆化搜索:这里的dp代表的是从后来所有点一路走来的最大权值,先不断递归,走到不能走了,就要返回,返回值是 dp[x][y]+a[x][y],然后回到上一层递归,继续for循环,再到走不动。。。。然后取max的最大值,这时候dp【x】【y】就已经是最优解了,以后遇到他直接返回就行;回溯完了dp【0】【0】就是从0,0走的最大值;
代码
bottom-up
#include <algorithm>#include <cstdio>#include <cstring>#include <iostream>#define N 105#define INF 0x7f7f7f7fusing namespace std;int n, k, cnt;int val[ N ][ N ];int dp[ N ][ N ];struct Node { int x, y; int v; bool operator< ( const Node n ) const { return v < n.v; }} node[ N * N ];bool path ( int a, int b, int x, int y ) { if ( a < 0 || a >= n || b < 0 || b >= n ) return false; if ( val[ a ][ b ] >= val[ x ][ y ] ) return false; if ( !dp[ a ][ b ] ) return false; return true;}int LIS () { int mx = 0; memset ( dp, 0, sizeof ( dp ) ); dp[ 0 ][ 0 ] = val[ 0 ][ 0 ]; // for ( int x = 0; x < n; ++x ) { // for ( int y = 0; y < n; ++y ) { for ( int p = 0; p < cnt; ++p ) { int x = node[ p ].x; int y = node[ p ].y; // 走i步 for ( int i = 1; i <= k; ++i ) { if ( path ( x - i, y, x, y ) ) dp[ x ][ y ] = max ( dp[ x ][ y ], dp[ x - i ][ y ] + val[ x ][ y ] ); if ( path ( x + i, y, x, y ) ) dp[ x ][ y ] = max ( dp[ x ][ y ], dp[ x + i ][ y ] + val[ x ][ y ] ); if ( path ( x, y - i, x, y ) ) dp[ x ][ y ] = max ( dp[ x ][ y ], dp[ x ][ y - i ] + val[ x ][ y ] ); if ( path ( x, y + i, x, y ) ) dp[ x ][ y ] = max ( dp[ x ][ y ], dp[ x ][ y + i ] + val[ x ][ y ] ); } if ( mx < dp[ x ][ y ] ) mx = dp[ x ][ y ]; } return mx;}int main () { while ( ~scanf ( "%d%d", &n, &k ) && n != -1 && k != -1 ) { cnt = 0; for ( int i = 0; i < n; ++i ) for ( int j = 0; j < n; ++j ) { scanf ( "%d", &val[ i ][ j ] ); node[ cnt ].x = i; node[ cnt ].y = j; node[ cnt++ ].v = val[ i ][ j ]; } sort ( node, node + cnt ); int sol = LIS (); printf ( "%d\n", sol ); } return 0;}
top-down
#include <algorithm>#include <cstdio>#include <cstring>#include <iostream>#define N 105#define INF 0x7f7f7f7fusing namespace std;int n, k;int val[ N ][ N ];int dp[ N ][ N ];int dir[ 4 ][ 2 ] = {1, 0, 0, 1, -1, 0, 0, -1};//下一个的坐标,当前的坐标bool path ( int a, int b, int x, int y ) { if ( a < n && b < n && a >= 0 && b >= 0 && val[ a ][ b ] > val[ x ][ y ] ) return true; return false;}int dfs ( int x, int y ) { if ( dp[ x ][ y ] ) return dp[ x ][ y ]; int ans = 0; for ( int j = 1; j <= k; ++j ) for ( int i = 0; i < 4; ++i ) { int xx = x + j * dir[ i ][ 0 ]; int yy = y + j * dir[ i ][ 1 ]; if ( path ( xx, yy, x, y ) ) ans = max ( ans, dfs ( xx, yy ) ); } return dp[ x ][ y ] = ans + val[ x ][ y ];}int main () { while ( ~scanf ( "%d%d", &n, &k ) ) { if ( n == -1 && k == -1 ) break; for ( int i = 0; i < n; i++ ) for ( int j = 0; j < n; j++ ) scanf ( "%d", &val[ i ][ j ] ); memset ( dp, 0, sizeof ( dp ) ); printf ( "%d\n", dfs ( 0, 0 ) ); } return 0;}
阅读全文
0 0
- hdu 1078 (dp记忆化搜索)
- [DP/记忆化搜索] HDU 1078
- HDU 1078 DP + 记忆搜索
- hdu 1078 FatMouse and Cheese(dp 记忆化搜索)
- hdu(1078) FatMouse and Cheese (记忆化搜索+dp)
- !HDU 1078 FatMouse and Cheese-dp-(记忆化搜索)
- HDU 1078 FatMouse and Cheese 简单DP&记忆化搜索
- HDU 1078 FatMouse and Cheese 记忆化搜索模板 dp
- HDU 1078 FatMouse and Chess(dp记忆化搜索)
- HDU 1078 FatMouse and Chess(dp记忆化搜索)
- [HDU 1078 ] FatMouse and Cheese [ dp 记忆化搜索 ]
- hdu :4359(记忆化搜索DP)
- hdu 4293 Groups dp 记忆化搜索
- hdu 2571 命运 (记忆化搜索+dp)
- HDU 1208 DP || 记忆化搜索
- HDU 1508 DP || 记忆化搜索
- hdu 4826(dp + 记忆化搜索)
- HDU 4968 DP||记忆化搜索
- 数据规整
- 最短路径问题---Dijkstra算法详解
- 树莓派3B 设置Linux下程序自启动
- 阿里云服务器Ubuntu16安装anaconda
- 7-3 分数拆分(Fractions Again?!)
- [DP/记忆化搜索] HDU 1078
- Maven学习总结系列七:聚合与继承
- 总结获取原生JS(javascript)的父节点、子节点、兄弟节点
- 231. Power of Two
- 动态代理完成字符集编码过滤器
- 每天一道LeetCode-----逆序链表
- leetcode 4 Median of Two Sorted Arrays(有坑待填)
- Spring Boot---(2)Spring Boot 配置文件详解
- Python3+OpenCV学习笔记(一):图像加载、显示和保存