ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 368|回复: 20

[讨论] agstick版主的捡金币问题

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-4-28 11:14 | 显示全部楼层 |阅读模式
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
先看题目

20071112111273324.gif

首先声明,本人对算法一窍不通。
本来想下载大佬的解法看看,但帖子里的附件一个也下载不了,不知怎么回事。
帖子里版主说要用动态规划法求解,于是搜了一下,
然后照着写了一个:

  1. Sub 捡金币_main()
  2. Range("a1:j10").Interior.ColorIndex = 0
  3. Range("a1:j10").Font.ColorIndex = 0

  4. arr = Range("a1:j10")
  5. Range("o7:o10") = ""

  6. Call 去程(arr)

  7. Call 回程(arr)

  8. End Sub
  9. Sub 去程(ByVal ar)


  10. ReDim br(1 To 10, 1 To 10) '存放累加值
  11. ReDim cr(1 To 10, 1 To 10) '存放路径
  12. ar(1, 1) = 0: ar(10, 10) = 0: cr(1, 1) = "A1" '初始值

  13. '第一列逐个累加
  14. For i = 2 To 10
  15.     br(i, 1) = br(i - 1, 1) + ar(i, 1)
  16.     cr(i, 1) = cr(i - 1, 1) & "->" & Cells(i, 1).Address(0, 0)
  17. Next
  18.    
  19. '第一行逐个累加
  20. For j = 2 To 10
  21.     br(1, j) = br(1, j - 1) + ar(1, j)
  22.     cr(1, j) = cr(1, j - 1) & "->" & Cells(1, j).Address(0, 0)
  23. Next

  24. 'br从第二行第二列开始循环,比较当前格的上一格和左一格的大小,(上,左都是累加值)
  25. '取较大的值+ar的当前值=br当前值
  26. For i = 2 To 10
  27.     For j = 2 To 10
  28.         If br(i - 1, j) > br(i, j - 1) Then
  29.             br(i, j) = br(i - 1, j) + ar(i, j)
  30.             cr(i, j) = cr(i - 1, j) & "->" & Cells(i, j).Address(0, 0)
  31.         Else
  32.             br(i, j) = br(i, j - 1) + ar(i, j)
  33.             cr(i, j) = cr(i, j - 1) & "->" & Cells(i, j).Address(0, 0)
  34.         End If
  35.     Next
  36. Next

  37. 'br(10,10)即为最大值
  38. [o7] = "去程捡到" & br(10, 10) & "金币"
  39. [o8] = "去程路径:" & cr(10, 10)

  40. '着色
  41. t = Split(cr(10, 10), "->")
  42. For Each cel In t
  43.     Range(cel).Font.ColorIndex = 3
  44. Next

  45. End Sub
  46. Sub 回程(ByVal ar)

  47. ReDim br(1 To 10, 1 To 10) '存放累加值
  48. ReDim cr(1 To 10, 1 To 10) '存放路径
  49. ar(1, 1) = 0: ar(10, 10) = 0
  50. cr(10, 10) = "J10"
  51.    
  52. For i = 9 To 1 Step -1
  53.     br(i, 10) = br(i + 1, 10) + ar(i, 10)
  54.     cr(i, 10) = cr(i + 1, 10) & "->" & Cells(i, 10).Address(0, 0)
  55. Next
  56.    
  57. For j = 9 To 1 Step -1
  58.     br(10, j) = br(10, j + 1) + ar(10, j)
  59.     cr(10, j) = cr(10, j + 1) & "->" & Cells(10, j).Address(0, 0)
  60. Next

  61.     For i = 9 To 1 Step -1
  62.         For j = 9 To 1 Step -1
  63.             If br(i + 1, j) > br(i, j + 1) Then
  64.                 br(i, j) = br(i + 1, j) + ar(i, j)
  65.                 cr(i, j) = cr(i + 1, j) & "->" & Cells(i, j).Address(0, 0)
  66.             Else
  67.                 br(i, j) = br(i, j + 1) + ar(i, j)
  68.                 cr(i, j) = cr(i, j + 1) & "->" & Cells(i, j).Address(0, 0)
  69.             End If
  70.         Next
  71.     Next

  72. [o9] = "回程捡到" & br(1, 1) & "金币"
  73. [o10] = "回程路径:" & cr(1, 1)
  74. t = Split(cr(1, 1), "->")
  75.     For Each cel In t
  76.         Range(cel).Interior.ColorIndex = 34
  77.     Next
  78. End Sub


复制代码


回程其实就是把数组倒过来循环,也不知版主说的”双线动态规划“是怎么样。
另外,没发现来回捡到金币数不一样的情况,有时路径不一样,但捡到金币数是一样的。
本人的算法对不对?
金币数不一样是什么情况?请各位大佬赐教。
捡金币2.zip (69.94 KB, 下载次数: 11)

TA的精华主题

TA的得分主题

发表于 2024-4-28 11:45 | 显示全部楼层
支持一下,看过好几次,双动态规划确实非常难懂。

TA的精华主题

TA的得分主题

发表于 2024-4-28 12:14 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
金币是有限的,去的时候捡到多少,原路返回的时候已没有金币捡了,只能走另一条路返回才能捡到,求的是一来一回捡到最多金币的最优解

TA的精华主题

TA的得分主题

发表于 2024-4-28 12:17 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-4-28 15:26 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助

原来是这个意思?

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-4-28 15:54 | 显示全部楼层
  1. Sub 双程捡金币()

  2. Range("a1:j10").Interior.ColorIndex = 0
  3. Range("a1:j10").Font.ColorIndex = 0
  4. Range("o7:o10") = ""

  5. ar = Range("a1:j10")
  6. ReDim br(1 To 10, 1 To 10) '存放累加值
  7. ReDim cr(1 To 10, 1 To 10) '存放路径
  8. ar(1, 1) = 0: ar(10, 10) = 0: cr(1, 1) = "A1" '初始值

  9. '第一列逐个累加
  10. For i = 2 To 10
  11.     br(i, 1) = br(i - 1, 1) + ar(i, 1)
  12.     cr(i, 1) = cr(i - 1, 1) & "->" & Cells(i, 1).Address(0, 0)
  13. Next
  14.    
  15. '第一行逐个累加
  16. For j = 2 To 10
  17.     br(1, j) = br(1, j - 1) + ar(1, j)
  18.     cr(1, j) = cr(1, j - 1) & "->" & Cells(1, j).Address(0, 0)
  19. Next

  20. 'br从第二行第二列开始循环,比较当前格的上一格和左一格的大小,(上,左都是累加值)
  21. '取较大的值+ar的当前值=br当前值
  22. For i = 2 To 10
  23.     For j = 2 To 10
  24.         If br(i - 1, j) > br(i, j - 1) Then
  25.             br(i, j) = br(i - 1, j) + ar(i, j)
  26.             cr(i, j) = cr(i - 1, j) & "->" & Cells(i, j).Address(0, 0)
  27.         Else
  28.             br(i, j) = br(i, j - 1) + ar(i, j)
  29.             cr(i, j) = cr(i, j - 1) & "->" & Cells(i, j).Address(0, 0)
  30.         End If
  31.     Next
  32. Next

  33. 'br(10,10)即为最大值
  34. [o7] = "去程捡到" & br(10, 10) & "金币"
  35. [o8] = "去程路径:" & cr(10, 10)

  36. '着色
  37. t = Split(cr(10, 10), "->")
  38. For Each cel In t
  39.     Range(cel).Interior.ColorIndex = 33
  40.     r = Range(cel).Row
  41.     c = Range(cel).Column
  42.     ar(r, c) = 0
  43. Next


  44. '=====================================================================
  45. '回程

  46. ReDim br(1 To 10, 1 To 10) '存放累加值
  47. ReDim cr(1 To 10, 1 To 10) '存放路径
  48. 'ar(1, 1) = 0: ar(10, 10) = 0
  49. cr(10, 10) = "J10"
  50.    
  51. For i = 9 To 1 Step -1
  52.     br(i, 10) = br(i + 1, 10) + ar(i, 10)
  53.     cr(i, 10) = cr(i + 1, 10) & "->" & Cells(i, 10).Address(0, 0)
  54. Next
  55.    
  56. For j = 9 To 1 Step -1
  57.     br(10, j) = br(10, j + 1) + ar(10, j)
  58.     cr(10, j) = cr(10, j + 1) & "->" & Cells(10, j).Address(0, 0)
  59. Next

  60.     For i = 9 To 1 Step -1
  61.         For j = 9 To 1 Step -1
  62.             If br(i + 1, j) > br(i, j + 1) Then
  63.                 br(i, j) = br(i + 1, j) + ar(i, j)
  64.                 cr(i, j) = cr(i + 1, j) & "->" & Cells(i, j).Address(0, 0)
  65.             Else
  66.                 br(i, j) = br(i, j + 1) + ar(i, j)
  67.                 cr(i, j) = cr(i, j + 1) & "->" & Cells(i, j).Address(0, 0)
  68.             End If
  69.         Next
  70.     Next

  71. [o9] = "回程捡到" & br(1, 1) & "金币"
  72. [o10] = "回程路径:" & cr(1, 1)
  73. t = Split(cr(1, 1), "->")
  74.     For Each cel In t
  75.         Range(cel).Interior.ColorIndex = 34
  76.     Next
  77. End Sub
复制代码

TA的精华主题

TA的得分主题

发表于 2024-4-28 19:09 | 显示全部楼层
有个事实,取得去程最大值,清除所检金币,再取得回程最大值,两者相加并不是最优解。看下面例子

*  1  8  2  *
*  3  9  4  *
*  *  *  *  *
*  *  *  *  *
*  *  *  *  *
去程 1+8+9+4=22 回程   3  最大 25

最优解 去程 1+8+2+4  =15(非去程最大) 回程 9+3=12  最大27

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-4-28 19:44 | 显示全部楼层
本帖最后由 yynrzwh 于 2024-4-28 19:49 编辑
lxdexcel 发表于 2024-4-28 19:09
有个事实,取得去程最大值,清除所检金币,再取得回程最大值,两者相加并不是最优解。看下面例子

*  1   ...

对哦,有什么解决思路吗?
我这方法只能找到单程的最大值。
双程最大值是不是只能用版主说的“双线动态规划“了?

TA的精华主题

TA的得分主题

发表于 2024-4-28 20:45 | 显示全部楼层
目的是求最优路径,所以证明算法错了。

所以从逻辑上,不能用最优路径走左上到右下,因为有的金币可以留给回程捡。

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-4-28 21:21 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
micch 发表于 2024-4-28 20:45
目的是求最优路径,所以证明算法错了。

所以从逻辑上,不能用最优路径走左上到右下,因为有的金币可以留 ...

是的,没什么思路了。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-5-12 09:49 , Processed in 0.043413 second(s), 12 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表