当前位置:   article > 正文

HDOJ 1044 Collecting More Jewels_hdu1044

hdu1044

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1044

此题系BFS和DFS的结合使用,需要理解BFS和DFS的特点。

BFS:对于解决最短或最少问题特别有效,而且寻找深度小,但缺点是内存耗费较大,需要开辟大量的数组单元来存储状态。

DFS:对于解决遍历和求所有问题有效,对于问题搜索深度小的时候处理迅速,然而在深度很大的情况下效率不高。

 

问题:在能够走出迷宫的前提下,如何尽可能多(价值之和大)的收集珠宝?

 

分析:

1、从题目可知,珠宝的数目及每个珠宝的价值我们能够知道,要求“最多”,我们通常会联想到动态规划。但从题目本身看,我们很难看到动态规划的影子。于是我们可以考虑构造动态规划的条件。

2、于是就有了这样的Idea:用BFS,先将“起始点--珠宝”、“珠宝--珠宝”、“珠宝—出口”两两间的最短距离求出来,构造一个新的图,用marix存储,matrix的每个元素即两个点之间的最短距离。

3、然后我们就可以利用动态规划(即这里的DFS)来求满足条件(能够走出迷宫;收集价值量最大的珠宝)的最优路径。

 

 

  1. #include<iostream>
  2. #include<queue>
  3. #include<ctype.h>
  4. #include<string.h>
  5. using namespace std;
  6. int T, W, H, M, L;
  7. char dungeon[60][60];
  8. int newMap[60][60];
  9. int value[60];
  10. int totalValue;
  11. int dis[60][60];
  12. int visited1[60][60];
  13. int visited2[60];
  14. int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
  15. int res;
  16. typedef struct{
  17. int x;
  18. int y;
  19. }Pos;
  20. queue<Pos> que;
  21. void bfs(int y, int x, int p)
  22. {
  23. int i;
  24. while(!que.empty()){
  25. que.pop();
  26. }
  27. Pos cur;
  28. cur.x = x;
  29. cur.y = y;
  30. visited1[y][x] = 1;
  31. dis[y][x] = 0;
  32. que.push(cur);
  33. while(!que.empty()){
  34. cur = que.front();
  35. que.pop();
  36. for(i=0; i<4; i++){
  37. Pos next;
  38. next.y = cur.y + dir[i][0];
  39. next.x = cur.x + dir[i][1];
  40. if(next.y>=H || next.y<0 || next.x>=W || next.x<0){
  41. continue;
  42. }
  43. if(visited1[next.y][next.x]==0 && dungeon[next.y][next.x]!='*'){
  44. visited1[next.y][next.x] = 1;
  45. dis[next.y][next.x] = dis[cur.y][cur.x] + 1;
  46. if(dungeon[next.y][next.x] == '@'){
  47. newMap[p][0] = dis[next.y][next.x];
  48. }
  49. if(isalpha(dungeon[next.y][next.x])){
  50. newMap[p][dungeon[next.y][next.x]-64] = dis[next.y][next.x];
  51. }
  52. if(dungeon[next.y][next.x] == '<'){
  53. newMap[p][M+1] = dis[next.y][next.x];
  54. }
  55. que.push(next);
  56. }
  57. }
  58. }
  59. }
  60. void dfs(int p, int v, int time)
  61. {
  62. if(time>L || res==totalValue){
  63. return ;
  64. }
  65. if(p>M && v>res){ //p=M+1说明能够走出去,当v>res时更新res
  66. res = v;
  67. }
  68. for(int i=0; i<=M+1; i++){
  69. if(newMap[p][i]==0 || visited2[i]){
  70. continue;
  71. }
  72. visited2[i] = 1;
  73. dfs(i, v+value[i], time+newMap[p][i]);
  74. visited2[i] = 0;
  75. }
  76. }
  77. int main()
  78. {
  79. int i, j, k, x;
  80. scanf("%d", &T);
  81. x = 1;
  82. while(T--){
  83. memset(visited2, 0, sizeof(visited2));
  84. memset(value, 0, sizeof(value));
  85. memset(newMap, 0, sizeof(newMap));
  86. scanf("%d%d%d%d", &W, &H, &L, &M);
  87. totalValue = 0; //totalValue是一个剪枝条件,不考虑会超时
  88. for(j=1; j<=M; j++){
  89. scanf("%d", &value[j]);
  90. totalValue += value[j];
  91. }
  92. value[0] = value[M+1] = 0;
  93. for(j=0; j<H; j++){
  94. scanf("%s", dungeon[j]);
  95. }
  96. for(i=0; i<H; i++){
  97. for(j=0; j<W; j++){
  98. memset(visited1, 0, sizeof(visited1));
  99. memset(dis, 0, sizeof(dis));
  100. if(dungeon[i][j]=='@'){
  101. bfs(i, j, 0);
  102. }
  103. if(isalpha(dungeon[i][j])){
  104. bfs(i, j, dungeon[i][j]-64);
  105. }
  106. if(dungeon[i][j] == '<'){
  107. bfs(i, j, M+1);
  108. }
  109. }
  110. }
  111. res = -1;
  112. visited2[0] = 1;
  113. dfs(0, 0, 0);
  114. printf("Case %d:\n", x++);
  115. if(res >= 0){
  116. printf("The best score is %d.\n", res);
  117. }
  118. else{
  119. printf("Impossible\n");
  120. }
  121. if(T){
  122. printf("\n");
  123. }
  124. }
  125. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/645532
推荐阅读
相关标签
  

闽ICP备14008679号