使用动态规划解决有关数字组合的问题

题目:在SHEET2中列出SHEET1表中重量不超过170,体积不超过200的所有组合(http://club.excelhome.net/viewthread.php?tid=382466&page=1#pid2435030)

 

Sheet1

 

序号重量体积
12530
22631
32732
42833
52934
63035
73136
83237
93338
103439
113540
123641
133742
143843
153944
164045
174146
184247
194348
204449
214550
224651
234752
244853
254954
265055
275156
285257
295358
305459
315560
325661
335762
345863
355964
366065
376166
386267
396368
406469

 

 

方法:动态规划,代码如下(可惜我的机子内存太小,无法定义更大的数组空间有效的完成此任务):

 

 

Sub getit()
    Dim s() As String, i&, j&, k&, l&, n&, t, v, w, temp$, sum1&, sum2&
    t = Sheet1.[a2:c41]
    sum1 = 170
    sum2 = 200
    ReDim s(UBound(t), sum1, sum2)

    For i = 1 To UBound(t)
        If t(i, 2) <= sum1 And t(i, 3) <= sum2 Then s(1, t(i, 2), t(i, 3)) = t(i, 1)
    Next

    For j = 2 To UBound(t)
        For k = 1 To sum1
            For l = 1 To sum2
                If s(j - 1, k, l) > "" Then
                    v = Split(s(j - 1, k, l))
                    For m = 0 To UBound(v)
                        If Not v(m) Like "*" & UBound(t) Then
                            w = Split(v(m), ",")
                            For i = Val(w(UBound(w))) + 1 To UBound(t)
                                If k + t(i, 2) <= sum1 And l + t(i, 3) <= sum2 Then s(j, k + t(i, 2), l + t(i, 3)) = Trim(s(j, k + t(i, 2), l + t(i, 3)) & " " & v(m) & "," & t(i, 1))
                            Next
                        End If
                    Next
                End If
            Next
        Next
    Next
    ReDim v(65535, 1 To 3)
    v(0, 1) = "序号"
    v(0, 2) = "重量"
    v(0, 3) = "体积"
    For k = 1 To sum1
        For l = 1 To sum2
            For j = 1 To UBound(t)
                If s(j, k, l) > "" Then
                    w = Split(s(j, k, l))
                    For m = 0 To UBound(w)
                        n = n + 1
                        v(n, 1) = w(m)
                        v(n, 2) = k
                        v(n, 3) = l
                    Next
                End If
            Next j, l, k
            Sheet2.[a1].Resize(n, 3) = v
        End Sub

 

运行结果(返回54414组解):

 

 

序号重量体积
12530
22631
32732
42833
52934
63035
73136
83237
93338
103439
113540
123641
133742
143843
153944
164045
174146
184247
194348
204449
214550
224651
234752
244853
254954
265055
275156
1,25161
285257
1,35262
295358
1,45363
2,35363
305459
1,55464
2,45464
315560
1,65565
2,55565
3,45565
325661
1,75666
2,65666
3,55666
335762
1,85767

................................

6,8,9,13,14170195
3,10,11,12,14170195
4,9,11,12,14170195
5,8,11,12,14170195
6,7,11,12,14170195
5,9,10,12,14170195
6,8,10,12,14170195
7,8,9,12,14170195
6,9,10,11,14170195
7,8,10,11,14170195
4,10,11,12,13170195
5,9,11,12,13170195
6,8,11,12,13170195
6,9,10,12,13170195
7,8,10,12,13170195
7,9,10,11,13170195
8,9,10,11,12170195
1,2,3,4,5,11170200
1,2,3,4,6,10170200
1,2,3,4,7,9170200
1,2,3,5,6,9170200
1,2,3,5,7,8170200
1,2,4,5,6,8170200

转载于:https://www.cnblogs.com/fengju/archive/2008/12/20/6336238.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值