B - 滑雪 POJ - 1088——dfs+记忆化搜索

阳光穿透心脏的1/2处 2022-06-11 04:06 340阅读 0赞

Think:
1知识点:dfs+记忆化搜索
1>记忆化搜索=搜索的形式+动态规划的思想
2>记忆化搜索简介:
记忆化搜索:算法上依然是搜索的流程,但是搜索到的一些解用动态规划的那种思想和模式作一些保存。
一般说来,动态规划总要遍历所有的状态,而搜索可以排除一些无效状态。
更重要的是搜索还可以剪枝,可能剪去大量不必要的状态,因此在空间开销上往往比动态规划要低很多。
记忆化算法在求解的时候还是按着自顶向下的顺序,但是每求解一个状态,就将它的解保存下来,
以后再次遇到这个状态的时候,就不必重新求解了。
这种方法综合了搜索和动态规划两方面的优点
——参考自百度百科
2题目分析:时间复杂度要求较高,单独dfs超时,需要记忆化记录中间已经得到的状态

以下为Accepted代码——16ms

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. int R, C, e[114][114], book[114][114];
  6. int jk[4][2]={
  7. {
  8. 0,1},{
  9. 1,0},{
  10. 0,-1},{-1,0}};
  11. int dfs(int x, int y);
  12. bool Judge(int dx, int dy);
  13. int main(){
  14. int i, j, mav;
  15. while(~scanf("%d %d", &R, &C)){
  16. memset(book, 0, sizeof(book));
  17. for(i = 1; i <= R; i++){
  18. for(j = 1; j <= C; j++){
  19. scanf("%d", &e[i][j]);
  20. }
  21. }
  22. mav = 1;
  23. for(i = 1; i <= R; i++){
  24. for(j = 1; j <= C; j++){
  25. mav = max(mav, dfs(i, j));
  26. }
  27. }
  28. printf("%d\n", mav);
  29. }
  30. return 0;
  31. }
  32. bool Judge(int dx, int dy){
  33. if(dx < 1 || dx > R || dy < 1 || dy > C)
  34. return false;
  35. else
  36. return true;
  37. }
  38. int dfs(int x, int y){
  39. if(book[x][y])
  40. return book[x][y];
  41. int k = 1;
  42. for(int i = 0; i < 4; i++){
  43. int dx = x + jk[i][0];
  44. int dy = y + jk[i][1];
  45. if(Judge(dx, dy) && e[dx][dy] < e[x][y])
  46. k = max(dfs(dx, dy)+1, k);
  47. }
  48. return book[x][y] = k;
  49. }

以下为Accetped代码——110ms

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. struct node{
  6. int x;
  7. int y;
  8. int w;
  9. }a[11400];
  10. int R, C, cnt, e[114][114], book[114][114], vis[114][114];
  11. int jk[4][2]={
  12. {
  13. 0,1},{
  14. 1,0},{
  15. 0,-1},{-1,0}};
  16. bool cmp(struct node aa, struct node bb){
  17. return aa.w < bb.w;
  18. }
  19. void dfs(int u, int v, int step);
  20. bool Judge(int dx, int dy);
  21. int main(){
  22. int i, j, u, v, ans;
  23. while(~scanf("%d %d", &R, &C)){
  24. int t1 = 0;
  25. for(i = 1; i <= R; i++){
  26. for(j = 1; j <= C; j++){
  27. scanf("%d", &e[i][j]);
  28. a[t1].x = i, a[t1].y = j, a[t1].w = e[i][j], t1++;
  29. }
  30. }
  31. sort(a, a+t1, cmp);
  32. ans = 1;
  33. memset(book, 0, sizeof(book));
  34. for(i = 0; i < t1; i++){
  35. u = a[i].x, v = a[i].y;
  36. cnt = 1;
  37. memset(vis, 0, sizeof(vis));
  38. vis[u][v] = 1;
  39. dfs(u, v, 1);
  40. book[u][v] = cnt;
  41. ans = max(ans, cnt);
  42. }
  43. printf("%d\n", ans);
  44. }
  45. return 0;
  46. }
  47. bool Judge(int dx, int dy){
  48. if(dx < 1 || dx > R || dy < 1 || dy > C)
  49. return false;
  50. else
  51. return true;
  52. }
  53. void dfs(int u, int v, int step){
  54. cnt = max(cnt, step);
  55. for(int i = 0; i < 4; i++){
  56. int dx = u + jk[i][0];
  57. int dy = v + jk[i][1];
  58. if(Judge(dx, dy)){
  59. if(book[dx][dy] && e[dx][dy] < e[u][v])
  60. cnt = max(cnt, step+book[dx][dy]);
  61. else if(e[dx][dy] < e[u][v]){
  62. vis[dx][dy] = 1;
  63. dfs(dx, dy, step+1);
  64. vis[dx][dy] = 0;
  65. }
  66. }
  67. }
  68. }

发表评论

表情:
评论列表 (有 0 条评论,340人围观)

还没有评论,来说两句吧...

相关阅读