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

来源:互联网 发布:淘宝延长发货 编辑:程序博客网 时间:2024/05/17 01:35

题目:在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

原创粉丝点击