ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: yynrzwh

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

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-4-29 09:20 | 显示全部楼层
才2048种。。。好像。。。直接暴力穷举。。。

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-4-29 10:21 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
morpheus126 发表于 2024-4-29 09:20
才2048种。。。好像。。。直接暴力穷举。。。

不止吧?写个代码看看?

TA的精华主题

TA的得分主题

发表于 2024-4-29 11:07 | 显示全部楼层
要算法,穷举肯定不适合,走一个来回18步,每一步有2个方向可选。穷举不是2048

TA的精华主题

TA的得分主题

发表于 2024-4-29 12:46 | 显示全部楼层
去的路线和回的路线可以交叉或重合一部分吗?当然数据只加一次。

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-4-29 15:09 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
大灰狼1976 发表于 2024-4-29 12:46
去的路线和回的路线可以交叉或重合一部分吗?当然数据只加一次。

应该是可以的

TA的精华主题

TA的得分主题

发表于 2024-4-29 15:11 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
加了回程确实比较难,去程最优解捡掉后加上回程最优解,不一定是整体最优解

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-4-29 15:11 | 显示全部楼层
穷尽了一下起点-终点路径,好象是48620种。
image.png

TA的精华主题

TA的得分主题

发表于 2024-4-29 21:17 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
这是一个用动态规划比较好解决的问题,如果只是单程话则是一个标准的动态规划的过程,先做一下单程。动态规划大概是按这样的步骤解决问题,1 ,分出阶段,前后阶段存在递推关系。2 根据递推关系找出转移方程 3 按阶段进行状态转移并寻找最优解。

这道题,我们以以走过的格子数分阶段,以k标识 k=0 ---19,假设格子坐标从0开始,以x,y标记,k解段格子状态集合是所有x+y=k的格子 比如 k=0:  0,0 , k=1: 0,1 ;1,0  ,k=3: 0,3;1,2;2,1;3,0; .........
'状态转移函数 :f(x,y)=max(f(x-1 ,y)+map(x,y),f(x,y-1+map(x,y))
以下是代码


Dim num&, max&
Dim map() As node


Public Type node
x As Long
y As Long
x1 As Long
y2 As Long
s As Long '捡的金币数
p As Long '路径方向 去程: 2 从上边来 1 从左边来,回程: 8 从上边来 4 从左边来,如果只求数量不显示路径可省略
End Type


Sub 开始()
Dim temp&(0 To 99), i&, n&, s&




ReDim map(0 To 9, 0 To 9)
Sheets("捡金币").Range("a1:j10").ClearContents
Sheets("捡金币").Range("a1:j10").Interior.Pattern = xlPatternNone
num = Sheets("捡金币").Range("m1")
max = Sheets("捡金币").Range("m2")


If num > 100 Then MsgBox "个数超出范围": Exit Sub


For i = 0 To 99
   
        temp(i) = i
   
Next


VBA.Randomize
For i = 0 To num - 1
    s = Int(max * Rnd + 1)
    n = Int(Rnd * (100 - i - 1))
    m = temp(n)
  Sheets("捡金币").Cells((m \ 10) + 1, (m Mod 10) + 1) = s
    map(m Mod 10, m \ 10).s = s
    temp(n) = temp(100 - i - 1)
Next




End Sub


Sub 单程() '仅计数
Dim s1&, s2&, k&, x&, y&


For k = 1 To 18
   For x = IIf(k < 10, 0, k - 9) To IIf(k < 10, k, 9) 'k阶段 if k<10,x取值范围0---k k>=10,x: k-9 ---9
     y = k - x
     s1 = map(x, y).s
     s2 = map(x, y).s
        
     If x > 0 Then s1 = map(x - 1, y).s + s1
           
     If y > 0 Then s2 = map(x, y - 1).s + s2
     
     
        map(x, y).s = IIf(s1 > s2, s1, s2)
        
   Next
  Next
  Sheets("捡金币").Range("p2") = map(9, 9).s


End Sub


Sub 单程1() '显示路径
Dim s1&, s2&, k&, x&, y&


For k = 1 To 18
   For x = IIf(k < 10, 0, k - 9) To IIf(k < 10, k, 9)
     y = k - x
     s1 = map(x, y).s
     s2 = map(x, y).s
        
     If x > 0 Then s1 = map(x - 1, y).s + s1
           
     If y > 0 Then s2 = map(x, y - 1).s + s2
     If s1 > s2 Then
     
        map(x, y).s = s1
        map(x, y).p = 1
     Else
        map(x, y).s = s2
        map(x, y).p = 10
        If s1 = s2 And y = 0 Then map(x, y).p = 1
     End If
   Next
  Next
  Sheets("捡金币").Range("t2") = map(9, 9).s
x = 9
y = 9




Do While 1
  Sheets("捡金币").Cells(y + 1, x + 1).Interior.ThemeColor = 6
   If map(x, y).p = 0 Then Exit Do
   
   If map(x, y).p = 1 Then
      x = x - 1
   Else
      y = y - 1
   End If


Loop
End Sub
如果有回程则问题复杂了些,但也是可以按动态规划的模式去解决

考虑以下几点:
1 对于回程可以转换为两个人从起点走到终点,这与一个人往返一次等效
2 阶段划分同单程一样
3 状态是两个点的组合
4 k阶段状态集合为 所有符合x+y=k的点(x,y)取两点所有不重复组合(形成组合的两点可以相同)
5 状态转移函数

f(x,y,x1,y1)=max(f(x-1 ,y,x1-1 ,y1)+map(x,y),
'                         f(x-1 ,y,x1 ,y1-1)+map(x,y)
'                         f(x ,y-1,x1-1 ,y1)+map(x,y)
'                         f(x ,y-1,x1 ,y1-1)+map(x,y) |x=x1 and y=y1,
'
'                         f(x-1 ,y,x1-1 ,y1)+map(x,y)+map(x1,y1),
'                         f(x-1 ,y,x1 ,y1-1)+map(x,y)+map(x1,y1)
'                         f(x ,y-1,x1-1 ,y1)+map(x,y)+map(x1,y1)
'                         f(x ,y-1,x1 ,y1-1)+map(x,y)+map(x1,y1) |x<>x1 or y<>y1)
'
'                 x+y =x1+y1

代码后续吧


TA的精华主题

TA的得分主题

 楼主| 发表于 2024-4-29 23:01 | 显示全部楼层
大神啊!
和版主的说法一样难懂。。。。

期待后续

TA的精华主题

TA的得分主题

发表于 2024-5-1 10:30 | 显示全部楼层
题目说动态规划是正解,那应该就是有DP办法解决。

因为是往返走,所以一个格子允许经过两次,那么状态转移的时候,一个格子就不是只看单程的方向最大就行
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-19 05:28 , Processed in 0.040466 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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