UVA 116 Unidirectional TSP

 C++代码 复制代码 收藏代码

  1. // [解题方法]
  2. // 记忆化搜索(递归,子问题的结果用备忘录存起来,避免重复求解)
  3. // 二维nxt数组按照题意记录路径
  4. // dp[x][y](即dfs(x,y))表示从(x,y)走到最右边需要的最小花费
  5.  
  6. #include <iostream>
  7. #include <string.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <algorithm>
  11. using namespace std;
  12. #define LL long long
  13. #define inf 1e16
  14.  
  15. LL dp[11][111],w[11][111], mins, res[105];
  16. int r, c;
  17.  
  18. struct point{
  19. int x, y;
  20. }nxt[11][111];
  21.  
  22. LL dfs (int x, int y)
  23. {
  24. if (y >= c) return (dp[x][y]=w[x][y]);
  25. if (dp[x][y] < 1e16)
  26. return dp[x][y];
  27. int i;
  28. LL tp = inf;
  29. for (i = x-1; i <= x+1; i++)
  30. {
  31. int tr = i;
  32. if (tr == 0) tr = r;
  33. else if (tr > r) tr = 1;
  34. LL tmp = dfs (tr, y+1) + w[x][y];
  35. //更新路径(花费更小+字典序)
  36. if (tmp < tp || (tmp == tp && tr < nxt[x][y].x)) {
  37. nxt[x][y].x = tr;
  38. nxt[x][y].y = y+1;
  39. tp = tmp;
  40. }
  41. }
  42. return (dp[x][y]=tp);
  43. }
  44.  
  45. int main()
  46. {
  47. int i, j;
  48. while (cin >> r >> c)
  49. {
  50. for (i = 1; i <= r; i++)
  51. for (j = 1; j <= c; j++)
  52. cin >> w[i][j], dp[i][j] = inf;
  53. mins = inf;
  54. int v;
  55. memset (nxt, -1, sizeof(nxt));
  56. for (i = 1; i <= r; i++)
  57. {
  58. LL tp = dfs (i, 1);
  59. if (tp < mins) {
  60. mins = tp;
  61. v = i;
  62. }
  63. }
  64. int tc = 1, k = 0;
  65. while (v > 0)
  66. {
  67. res[k++] = v;
  68. int tv = v;
  69. v = nxt[tv][tc].x;
  70. tc = nxt[tv][tc].y;
  71. }
  72. cout << res[0];
  73. for (i = 1; i < k; i++) cout << ' ' << res[i];
  74. cout << endl << mins << endl;
  75. }
  76. return 0;
  77. }  

你可能感兴趣的:(6+)