UVA 10913 - Walking on a Grid (记忆化搜索)

举报
Linux猿 发表于 2021/08/05 01:26:40 2021/08/05
【摘要】 题目链接~~> 做题感悟:开始不用标记数组把 dp 数组初始化一下用于标记但是这样因为初始化的原因就超时了,改为标记数组才过。 解题思路:记忆化搜索                 这题很明显,如果用递推的方法的话必定不好写,因为在一行里可以向左做可以向右走,这样就导致不好递推,如果用...

题目链接~~>

做题感悟:开始不用标记数组把 dp 数组初始化一下用于标记但是这样因为初始化的原因就超时了,改为标记数组才过。

解题思路:记忆化搜索

                这题很明显,如果用递推的方法的话必定不好写,因为在一行里可以向左做可以向右走,这样就导致不好递推,如果用记忆化方法的话就很好写了,如果单纯的只向右和下的话可以用三维标记 dp[ i ] [ j ] [ k ] (代表到达第i行第 j 列经历了 k 个负数所得到的最优值) ,这里还可以向左走,so~> 必须必须加一维方向,标记是从哪个方向得到的,放置重复走 ,即: dp [ i ] [ j ] [ k ] [ d ]  代表到达第 i 行第 j 列出现了 k 个负数从方向 d 得到的最优解。

代码:


  
  1. #include<iostream>
  2. #include<ctime>
  3. #include<fstream>
  4. #include<sstream>
  5. #include<stack>
  6. #include<cstring>
  7. #include<map>
  8. #include<vector>
  9. #include<cstdio>
  10. #include<algorithm>
  11. #define INT long long int
  12. using namespace std ;
  13. const INT INF = 999999999 ;
  14. const INT MY = 10 ;
  15. const INT MX = 75 + 5 ;
  16. INT n ,k ;
  17. bool vis[MX][MX][MY][MY] ;
  18. INT dp[MX][MX][MY][MY] ,g[MX][MX] ;
  19. INT dx[4]={1 ,0 ,0} ,dy[4]={0 ,-1 ,1} ;
  20. void input()
  21. {
  22. for(INT i = 0 ;i < n ;i++)
  23. for(INT j = 0 ;j < n ;j++)
  24. scanf("%lld",&g[i][j]) ;
  25. memset(vis ,false ,sizeof(vis)) ;
  26. }
  27. INT DP_Memory(INT x ,INT y ,INT z ,INT d)
  28. {
  29. if(z > k) return -INF ;
  30. if(x==n-1 && y == n-1)
  31. return g[x][y] ;
  32. if(vis[x][y][z][d])
  33. return dp[x][y][z][d] ;
  34. vis[x][y][z][d] = true ;
  35. INT& ans = dp[x][y][z][d] ;
  36. ans = -INF ;
  37. for(INT t = 0 ;t < 3 ;t++)
  38. {
  39. INT sx = x + dx[t] ;
  40. INT sy = y + dy[t] ;
  41. if(d + t == 3) continue ;
  42. if(sx >= 0 && sy >= 0 && sx < n && sy < n)
  43. {
  44. INT mx = (g[sx][sy] < 0) ;
  45. INT my = DP_Memory(sx ,sy ,z+mx ,t) ;
  46. if(my != -INF)
  47. ans = max(my + g[x][y] ,ans) ;
  48. }
  49. }
  50. return ans ;
  51. }
  52. int main()
  53. {
  54. int cse = 1 ;
  55. while(scanf("%lld%lld",&n ,&k) ,n+k)
  56. {
  57. input() ;
  58. INT x = (g[0][0] < 0) ,ans = -INF ;
  59. ans = DP_Memory(0 ,0 ,x ,0) ;
  60. cout<<"Case "<<cse++<<": " ;
  61. if(ans != -INF)
  62. cout<<ans<<endl ;
  63. else cout<<"impossible"<<endl ;
  64. }
  65. return 0 ;
  66. }


文章来源: blog.csdn.net,作者:Linux猿,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/nyist_zxp/article/details/38495243

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。