我有个数组a,个数和数值任意
现从该数组连续的三个位置取出1或0,只要连续,不一定要从第一个开始。
直到将所有数取完为止。
求最好的排列和取法(可能有N种方法是正确的)。
例如:a(0)=1,a(1)=2,a(2)=2,a(3)=3,a(4)=3
最好的排列和取法:
排列 2  3  3  2  1
取法 1  1  1
     1  1  1
        1  1  1
           0  1  1

解决方案 »

  1.   

    好像可以了~Private Sub Form_Click()
        Me.FontName = "宋体"
        
        Me.Print xSolve("2,3,3,2,1")
        Me.Print xSolve("1,1,2,2")
        Me.Print xSolve("1,2,2,3,3,1")
    End SubPrivate Function xSolve(strV As String) As String
        Dim i As Integer, j As Integer
        Dim a As Integer, b As Integer, c As Integer
        Dim tS() As String, RetS As String
        Dim tV() As Integer
        Dim tUB As Integer
        
        '初值……
        tS = Split(strV, ",")
        tUB = UBound(tS)
        ReDim tV(tUB) As Integer
        
        For i = 0 To tUB
            tV(i) = Val(tS(i))
        Next
        Erase tS
        
        '原题……
        For i = 0 To tUB
            RetS = RetS & Format(tV(i), "@@@")
        Next
        RetS = RetS & vbCrLf & String$((tUB + 1) * 3, "=") & vbCrLf    '求解……
        Do
            '定位到c
            b = 0
            For i = 0 To tUB - 2
                a = 0
                For j = 0 To 2
                    a = a + tV(i + j)
                Next
                If b < a Then b = a: c = i
            Next
            If b = 0 Then Exit Do
            
            '减值
            RetS = RetS & String$(c * 3, " ") '前导空格
            For i = c To c + 2
                If tV(i) > 0 Then
                    tV(i) = tV(i) - 1
                    RetS = RetS & "  1"
                Else
                    RetS = RetS & "  0"
                End If
            Next
            RetS = RetS & vbCrLf
        Loop While b > 0
        
        
        xSolve = RetS
        Erase tV
    End Function
      

  2.   

    本来在开始写穷举的代码了……
    突然又想到可以这样改下~        '定位到c
            b = 0
            For i = 0 To tUB - 2
                a = 0
                For j = 0 To 2
                    If tV(i + j) > 0 Then a = a + 1
                Next
                If a > 0 And tV(i) > 0 Then
                    b = a
                    c = i
                    Exit For
                End If
            Next
            If b = 0 Then Exit Do
      

  3.   

    不难
    Option ExplicitSub Main()
        X "1,2,2,3,3"
        X "1,1,2,2"
        X "1,0,1,1,1,1"
        X "1,1,2,2,2,2,2,1,1"
    End SubSub X(ByVal List As String)
        Dim oList           As Collection
        Dim a1()            As Long
        Dim a2()            As String
        Dim a3()            As String
        Dim lUB             As Long
        Dim I               As Long
        Dim J               As Long
        
        Set oList = Sort(List)
        lUB = oList.Count - 1
        ReDim a1(0 To lUB)
        ReDim a2(0 To lUB)
        ReDim a3(0 To lUB)
        I = 0
        While oList.Count
            Select Case oList.Count
                Case 1
                    a1(I) = oList(1):        oList.Remove 1:    a2(I) = a1(I)
                Case 2
                    a1(I + 1) = oList(1):    oList.Remove 1:    a2(I + 1) = a1(I + 1)
                    a1(I) = oList(1):        oList.Remove 1:    a2(I) = a1(I)
                Case Else
                    a1(I + 2) = oList(1):    oList.Remove 1:    a2(I + 2) = a1(I + 2)
                    a1(I + 1) = oList(1):    oList.Remove 1:    a2(I + 1) = a1(I + 1)
                    a1(I) = oList(1):        oList.Remove 1:    a2(I) = a1(I)
                    
                    Do While oList.Count
                        a1(I + 2) = a1(I + 2) - a1(I)
                        a1(I + 1) = a1(I + 1) - a1(I)
                        a1(I) = 0
                        
                        If a1(I + 1) > 0 Then
                            a1(I + 3) = oList(1):    oList.Remove 1:    a2(I + 3) = a1(I + 3)
                            
                            I = I + 1
                        ElseIf a1(I + 2) > 0 Then
                            If I + 4 <= lUB Then
                                a1(I + 4) = oList(1):    oList.Remove 1:    a2(I + 4) = a1(I + 4)
                                If oList.Count = 0 Then Exit Do
                            End If
                            a1(I + 3) = oList(1):    oList.Remove 1:    a2(I + 3) = a1(I + 3)
                        
                        
                            I = I + 2
                        Else
                            I = I + 3
                            Exit Do
                        End If
                    Loop
            End Select
        Wend
        
        Debug.Print String(40, "=")
        Debug.Print Join(a2, vbTab)
        Debug.Print String(40, "-")
        I = 0
        While I <= lUB
            ReDim a3(0 To lUB)
            For J = I To I + 2
                If J <= lUB Then
                    If a2(J) > 0 Then
                        a2(J) = a2(J) - 1
                        a3(J) = 1
                    End If
                Else
                    Exit For
                End If
            Next
            Debug.Print Join(a3, vbTab)
            
            J = I
            Do While a2(J) = 0
                J = J + 1
                If J > lUB Then Exit Do
            Loop
            I = J
        Wend
    End SubFunction Sort(ByVal List As String) As Collection
        Dim Result          As Collection
        Dim a()             As String
        Dim I               As Long
        Dim J               As Long
        Dim L               As Long    Set Result = New Collection
        
        a = Split(List, ",")
        For I = 0 To UBound(a)
            L = a(I)
            
            If Result.Count = 0 Then
                Result.Add L
            Else
                J = 1
                Do While Result(J) > L
                    J = J + 1
                    If J > Result.Count Then Exit Do
                Loop
                
                If J > Result.Count Then
                    Result.Add L
                Else
                    Result.Add L, , J
                End If
            End If
        Next
        Set Sort = Result
    End Function
      

  4.   

    Tiger_Zhao的不错啊~只是觉得如果不排序的话
    这个题会有意思点……嗯~继续~~
      

  5.   

    Tiger_Zhao的不错,回去研究下。谢谢
      

  6.   

    上午上班,有点事,写了理论部分,楼主将就看下,估计晚上来交程序.
    一、计算次数:
        我们讨论数组的排列问题无非是为了最快的把数组里的数取完,也就是用最少的计算次数把数组里的全部值减到零为止。那么计算的次数跟什么有关那?以两组数据举个例子:
        A组: 1 3 4 3 1      B组: 1 1 3 3 4
              1 1 1                1 1 1
                1 1 1                  1 1 1
                1 1 1                  1 1 1
                  1 1 1                0 1 1
                                       0 0 1
    从这个例子很容易看出,相同的数据,A组用了4次,而B组用了5次,所以当数据以正态分布的时候,计算的次数最少。二、绝对正态分布与相对正态分布:
        大家都知道什么是正态分布,但在我们这道题里还要讲另外一个知识,就是正态分布跟正态分布是不一样的,比如:
        A组:  1 1 4 3 3          B组:1 3 4 3 1
    不确切的说,这两组数据都可以看成是正态分布,他们都遵循着 (低-高-低)规律,我们把A组数据的分布情况叫相对正态分布,B组数据的分布情况叫绝对正态分布,那么究竟哪个分布更能使计算次数更少那?答案是两者都一样。(可以换组数据试试看)
        A组:  1 1 4 3 3          B组: 1 3 4 3 1
               1 1 1                    1 1 1
                   1 1 1                  1 1 1
                   1 1 1                  1 1 1
                   1 1 1                    1 1 1
    三、数据的分组:
        上面的例子,只是以5个数的数组为例,其实以5个数为例是有目的的,这是因为题要求必须连续取3位,而在这种情况下要形成正态分布的最小数当然就是5了。
         既然正态分布的数据减值最快(计算次数最少),那么,我们把一个很长的数组先给它分一下组,每组5个数据,而且每组内的5个数据都成正态分布(绝对为佳),然后《连续》的对每个组进行处理,这样就可以达到减值最快的效果了。
         这时,有人会想到,组与组之间是如何连接处理的?很简单,每个组总体的值要比上一组大,也就是组之间成递增规律就可以了。比如下面的例子:
         12321 45654 78987  这是一个有15个元素的被分完组的数组,他们被分为3组,每组5个元素,而且每组里面成绝对正态分布,组之间成递增规律。为这样的数组起名叫华组。
         这就是我们想要的数组的排序!那么一个随即产生的数组究竟应该怎么处理最后才能得到华组那?很简单
         一个随即数组经过下面几步就可以得到华组:
         第一步:对整个数组进行排序 : 小——>大
         第二步:对整个数组进行分组 : 每组5个
         第三步:对每组里面的元素进行重新排序: 按照绝对正态分布排序
      这样,我们就可以得到一个能减值最快的数组了(既华组)。程序稍后播出。
      

  7.   

    楼上的楼上没有在理论上证明绝对正太分布的才是最佳排列,没有理论证明的可以说都有漏洞 Tiger_Zhao程序还没看,不知算法是什么,穷举?
    如果不是的话,有什么依据?
    一点说明都没有,真晕
      

  8.   

    To : flyingscv(zlj) 
    请仔细看,第一部分的例子意在证明,正态分布是计算次数最少的排列方法.而第二部分是说,绝对与相对都可以(只是我认为绝对更好些)//
    我承认,或许这不是最好的,如果你有更好的排列方案不妨拿出来大家一起研究下.**其实,推理部分比我上面写的要多,我只把简要的写上去.
    下面是我按照绝对正态分布排序的方案写的程序,这个程序已经实现,这个程序能处理长度为5的倍数的数组,楼主可以稍微改动一下,便可以处理任意长度的数组.
    程序如下:
    command1_click() 事件生成一个长度为15的随机数组
    command2_click()  事件对该数组做由小到大的排序
    command3_click()  事件生成华组(即楼主要的减值最快的排序结果)
    分为三个按钮来写这个程序目的是为了读起来方便
    以下是代码部分:Dim a(14) As Integer '通用
    Private Sub Command1_Click()
    '生成随即数组
    Print
    For i = 0 To 14
    Randomize
    a(i) = Int(Rnd * 10)
    Print a(i);
    Next i
    Print
    End SubPrivate Sub Command2_Click()
    '对随即数组的排序:小->大
    Dim t As Integer
    For i = 0 To 13
        For j = i + 1 To 14
        If a(i) > a(j) Then
           t = a(i)
           a(i) = a(j)
           a(j) = t
        End If
        Next j
        Print a(i);
    Next i
    Print a(i);
    Print
    End SubPrivate Sub Command3_Click()
    '生成华组
    Dim j As Integer
    j = 3 '数组的个数
    For j = 1 To 3
    i = (j - 1) * 5     '设置每组数的下界
    '对每数组里的数排序,按从小到大的顺序为1,5,2,4,3
    '把2跟5交换
    t = a(i + 1)
    a(i + 1) = a(i + 4)
    a(i + 4) = t
    '把2跟3交换
    t = a(i + 1)
    a(i + 1) = a(i + 2)
    a(i + 2) = t
    For t = i To i + 4
    Print a(t);
    Next t
    Print ,
    Next j
    End Sub
      

  9.   

    我写程序的时候午夜两点多,没精力写注释,不好意思。这个算法的关键要把数组排序,尽量使得每次取走最多的数(理想情况为 3 个 1)。
    我设定取数规则为从最左边非零的数组元素开始,连续取 3 个 1(除非数组元素不足或后续元素已为零)。这就是 Sub X() 最后的 Debug.Print 开始部分,没什么好解释的。按照我的取法,其实是对数组中连续的三个元素 a, b, c
    取 a 次 3 个 1,剩下的 a', b', c' 的值为 0, (b-a), (c-a)
    考虑到取数规则,显然让 b<a 或 c<a 是浪费的,应该使得 b-a>=0 和 c-a>=0,这样b', c' 能够与后续元素 d 作为取数目标进入下一个取数循环。同样应该使得 c'>=b' 最好 d>= b'
    所有前四个元素 a, b, c, d 的设置规则应该是
      a<=b<=c
      d 尽量大
    考虑到排在数组后面的元素,非常可能在(从左至右的)取数过程中无法组成整 3 个取数目标,那么后面的元素就应该尽量小
      

  10.   

    Tiger_Zhao的想法很奇特
    今天有点事,看的还不是很明白,
    刚才真好碰巧试了一个序列3,4,5,6,7,6,7,发现你的程序不适用我感觉对最佳问题类的算法除了穷举算法之外(因为穷举的严密性是不用证明的)
    其它的算法都应该有严密的逻辑证明来保证结果
      

  11.   

    Tiger_Zhao的这个算法应该没有问题吧~=========================
    6   7   7   6   4   5   3
    -------------------------
    1   1   1               
    1   1   1               
    1   1   1               
    1   1   1               
    1   1   1               
    1   1   1               
        1   1   1           
                1   1   1   
                1   1   1   
                1   1   1   
                1   1   1   
                1   0   1   
                    0   0   1
                    0   0   1
                    0   0   1这个3,4,5,6,7,6,7把3那一列去掉
    结果肯定是最优的(把4换成5更直观,不会出现0)然后再加一个3进去
    3应该就只能单独消除了有更好的解法么?
    另外……
    关于解不排序的的原始序列
    除了穷举还真没有好的想法……
    大家有兴趣就研究下吧~ ^ ^
      

  12.   

    To: flyingscv(zlj)
    看了你回复,我想问你几个问题
     1 你是否知道穷举的含义? 2 以及穷举在哪方面应用?
    然后,我要告诉你,此题跟穷举毫无关系.
    穷举是当题的解无规律可寻的时候,要一一列举看是否符合解,这道题的关键是数的排序,你能说数之间没有规律?最主要的,一道排序问题怎么可能跟穷举联系到一起?
    我已经看了 Tiger_Zhao程序,他的方法根本不是穷举法,仔细看,他是在推理数的正态分布!
      

  13.   

    AprilSong
    3 4 5 6 7 6 7
    我手工排了一次的结果要14次,还不知是不是最佳排列,
    我还没编穷举的程序,看了Tiger_Zhao的说明就构造了这个试了一下
    我用的较佳排列是6677543to ylsn2004:
    应该是你误会了我的意思
    我说的穷举的意思是列出所用可能的情况,通过比较得出最佳结果
    这里的所有可能情况可以是经过理论证明最小可能排列
    应该说这是计算机最适用的地方
    我想数据结构中的最简单的迷宫求解到最短路径都是以这个为基础的吧(我是这么理解的)
    不知我说清楚了没有
    Tiger_Zhao的程序确实不是穷举,所用的最佳排列是建立在假设基础之上的对于这道题,如果用穷举的话
    对任一个排列,都可以列出所有取法,来找出最好的取法
    而对任一数组可以列出所有排列,找出取法最好的那些就行了我说过“不过这个问题穷举可能是最好的方法”
    我只是说可能。熟归熟啊,呵呵
    我说这个是因为
    那天我想了之后感觉不是没有什么思路
    而是完全没有思路
    所以说出来看有没有同感的,就像AprilSong现在就是这种想法:)对这种算法题,总希望能总结出规律,享受其中的乐趣
    当然希望有一天能找到更好的算法
      

  14.   

    这个问题关键是最佳排列的求法,看来只能用穷举了给一个求最佳取法所需步数的函数,这个比较简单
    Public Function GetCount(b() As Long) As Long
    '返回取完指定排列所需最少步数
    'b()为要取的数组
        Dim i As Long
        Dim BD As Long
        
        BD = UBound(b)
        For i = LBound(b) To BD - 2
            If b(i) > 0 Then
                GetCount = GetCount + b(i)
                b(i + 1) = b(i + 1) - b(i)
                b(i + 2) = b(i + 2) - b(i)
            End If
        Next i
        
        If b(BD - 1) > b(BD) Then
            If b(BD - 1) > 0 Then
                GetCount = GetCount + b(BD - 1)
            End If
        Else
            If b(BD) > 0 Then
                GetCount = GetCount + b(BD)
            End If
        End If
    End Function
    等晚上我把穷举的最佳排列的算法也写出来算了
      

  15.   

    那么,减3(也就是111)怎么样才能出现的几率最大?
    看例子:
    1 3 4 3 1 这是一个5个元素的数组的一种排序情况,而且这种排序情况是减值最快的,也就是111能出现的几率最多的情况,这种情况就是正态分布!!!!!!!To flyingscv(zlj)
    请你别编写取法了,取法是固定的,就是3最多,2次之,1最少,OK?
    这个取法非常的简单,概括起来就一句话:
    对于连续取值的三个数,(1)每位大于0的时候取1 ,等于0取0(2)第一位取完后,第四位补,第二位变第一位,第三位变第二位,依次往下类推。      
      

  16.   

    咱胡汉三又回来了!:P
    有了宝宝难得有空,各位见谅了。接上回
    设 oList 为以排序的未分配元素,用 oList.Pop() 表示取出最大元素。
    生成最优数组:状态1:
    c = oList.Pop() ' c 分配最大值
    b = oList.Pop() ' b 分配次大值
    a = oList.Pop() ' a 分配第三大值状态2:
    a, b, c 作为最优数组的连续元素,可以取 a 次 3 个 1,剩余a' = a - a = 0
    b' = b - a
    c' = c - aIf b' <> 0 Then
      状态3:
      d = oList.Pop() 'd 分配剩余元素中的最大值  将 b', c', d 对照为 a, b, c;Go To 状态2
    ElseIf c' <> 0 Then
      状态4:
      e = oList.Pop() 'e  分配剩余元素中的最大值
      d = oList.Pop() 'e  分配剩余元素中的次大值  将 c', d, e 对照为 a, b, c;Go To 状态2
    Else
      Go To 状态1
    End If其他无非就是当 oList 为空后结束分配的处理。
      

  17.   

    已 oList = {7,7,6,6,5,4,3} 为例分配 {6,7,7, , , , } 余 oList = {6,5,4,3}
    取6次 1,1,1
    剩余 {0,1,1, , , , } 
    分配 { , , ,6, , , } 余 oList = {5,4,3}
    取1次   1,1,1
    剩余 {0,0,0,5, , , }
    分配 { , , , ,4,5, } 余 oList = {3}
    取4次       1,1,1
    取1次       1,0,1
    剩余 {0,0,0,0,0,0, }
    分配 { , , , , , ,3} 余 oList = {}
    取3次             1
    结束优化数组为 {6,6,7,5,4,5,3}
    需要取数 15 次
      

  18.   

    楼上当爸爸了啊,哈哈
    程序出来了,计算最佳排列使用穷举
    运行需要加一个 textbox,一个commandbox3,4,5,6,7,6,7的最佳排列为3,5,6,4,7,7,6
    需要13步Option Explicit
    Private OriginA() As Long '数据下标基于1
    Private ArrangeA() As Long '数据下标基于1
    Private BestA() As Long  '数据下标基于1
    Private BestCount As LongPrivate Sub Command1_Click()
        Dim a() As Long  '用于ArrangeDistinct
        Dim b() As String
        Dim s As String
        Dim i As Long
        Dim BD As Long
        
        b = Split(Text1.Text, ",")
        BD = UBound(b) + 1
        
        ReDim OriginA(BD)
        ReDim ArrangeA(BD)
        ReDim BestA(BD)
        ReDim a(BD)
        
        BestCount = 2147483647 '不考虑超过这么多次的数据
        
        For i = 0 To UBound(b)
            OriginA(i + 1) = b(i)
        Next i
        
        ArrangeDistinct a, 1
        
        For i = 1 To BD
            s = s & Str(BestA(i))
        Next
        Print "------------------------------------------"
        Print Text1.Text & "的最佳排列为:" & s
        Print "最少需要:" & BestCount & "次"
    End SubPublic Function GetCount(b() As Long) As Long
    '返回取完指定排列所需最少步数,下标基于1
    '最佳取法原理很简单,就是开始取到尾
        Dim i As Long
        Dim BD As Long
        
        BD = UBound(b)
        For i = LBound(b) To BD - 2
            If b(i) > 0 Then
                GetCount = GetCount + b(i)
                b(i + 1) = b(i + 1) - b(i)
                b(i + 2) = b(i + 2) - b(i)
            End If
        Next i
        
        If b(BD - 1) > b(BD) Then
            If b(BD - 1) > 0 Then
                GetCount = GetCount + b(BD - 1)
            End If
        Else
            If b(BD) > 0 Then
                GetCount = GetCount + b(BD)
            End If
        End If
    End FunctionPublic Function GetBestArray(b() As Long) As LongEnd FunctionPublic Function ArrangeDistinct(b() As Long, Optional ByVal Num As Long = 1) As Long
    '功能全排列数组,每次排列调用一次Arrange
    '调用方法   ArrangeDistinct b
    'b下标基于1
        Dim BD As Long
        Dim i As Long, j As Long
        Dim exist As Boolean
        
        BD = UBound(b)
            
        If Num > BD Then
            Arrange b
        Else
            For i = 1 To BD
                b(Num) = i
                exist = False
                
                For j = 1 To Num - 1
                    If b(j) = i Then
                        exist = True
                        Exit For
                    End If
                Next j
                
                If Not exist Then
                    ArrangeDistinct b, Num + 1
                End If
            Next i
        End If
        
    End FunctionPublic Function Arrange(b() As Long) As Long
    '全排列调用函数由ArrangeDistinct或者ArrangeAll调用    Dim BD As Long
        Dim i As Long
        Dim s As String
        Dim Count As Long
        
        BD = UBound(b)
        For i = 1 To BD
            ArrangeA(i) = OriginA(b(i))
        Next i
        
        Count = GetCount(ArrangeA)
        
        If Count < BestCount Then
            For i = 1 To BD
                BestA(i) = OriginA(b(i))
            Next i
            BestCount = Count
        End If
        
    End Function
    Private Sub Form_Load()
        Text1.Text = "3,4,5,6,7,6,7"
    End Sub
      

  19.   

    感谢flyingscv(zlj) 找到了理想解:RoundUp(∑{3,4,5,6,6,7,7}/3) = RoundUp(38/3) = 13 次状态3 和 状态4 中对 d, e 分配的假设不正确,如何改进?
      

  20.   

    谢谢各位的支持。
    开始感觉Tiger_Zhao(VB老鸟)的算法应该可以了。没想到用穷举居然还能找到更好的解。但穷举的话太慢了,数组个数少还可以,一多就不行了。应该还有更好的方法
      

  21.   

    状态3 和 状态4 中对 d, e 分配的假设不正确,如何改进?
    ------------------------------------
    我想这样改进也许就行了If b' <> 0 Then
      状态3:
      d = oList.Pop() 'd 分配剩余元素中的最大值这里不应该取最大的
    我的看法(你看看啊,不知是不是说清楚了)
    d = oList.Pop()
    if b'>d  then goto 状态1
    否则
    e= oList.Pop()
    if d-b'<e goto 状态1
    否则
    swap(d,e)
    goto 状态1其它状态和这个类似这样也许就是最佳了,可以用穷举验证看看
      

  22.   

    是啊,作为猜测,无法证明是最佳。
    理想(可能的最小)解为 RoundUp(∑{所有元素}/3) 次,但是象数组 {5,5,5,5} 就无法用 7 次取完。
    我也考虑过在出现没有取满 3 的情况下(比如猜测到 {6,6,7,5,4,5, } 时出现取数 1,0,1)进行回溯,执行有限的穷举;但是无法判断是否有必然存在无法取满 3 的情况。
      

  23.   

    引用 ylsn2004(碧海青天) 说的:
    -------------------------------------------------------------------------
    取0或者1(每位)
    那么连续取三位只有下面这个几种取法或者是其中的几个组合:
    111(减3)
    110,101,011(减2)
    001,010,100(减1)而且,可以说取法是固定的,因为要减的最快,那么就要减3出现的几率最大,减2次之,减1最少。
    ---------------------------------------------------------------------------题目的解就是要使减3出现的次数最多,减2的次之,减1的最少数列的和S=Σa,取一次最多减3,所以理论上最少取的次数为ceil(S/3),3+4+5+6+7+6+7=38,所以最少要ceil(38/3)=13次
    ( ceil(x)表示大于或等于x的数中最小的数 )数列a1,a2,a3,…,an取1,1,1的过程可以当成多项式除法,比如                     3,2,1,1,5
                ———————————
    (1,1,1)∫(3,5,6,4,7,7,6)
                  3,3,3
                -----------------------
                      2,3,4
                      2,2,2
                -----------------------
                         1,2,7
                         1,1,1
                -----------------------
                            1,6,7
                            1,1,1
                -----------------------
                               5,6,6
                               5,5,5
               ------------------------
                               0,1,1所以我们先来看看:多项式(a1,a2,a3,…,an)能被(1,1,1)“整除”的时候,数字a1,a2,a3,…,an的特征。联想到能被11整除的数的规律:
    奇数位的和 = 偶数位的和,猜想:
        
         (a1,a2,a3,…,an)能被(1,1,1)“整除”                   -----------------------<1>
    <=====>(a1,a2,a3,…,an)=(b1,n2,b3,…,bm)×(1,1,1)       -----------------------<2>
    <=====> a1+a4+a7+… = a2+a5+a8+… = a3+a6+a9+… = b1+b2+…+bm    -----------------------<3>
    其中 m=n-2即把a1,a2,a3,…,an分成3组,每隔2位加起来,得3个和,这3个和相等这个猜想通过数学归纳法可以推理出来,具体推理过程我就不写了(偶的表达不好*^_^*)举个例子:
    (a,b,c,d,e,f)×(1,1,1)=(a,a+b,a+b+c,b+c+d,c+d+e,d+e+f,e+f,f)
    a1=a
    a2=a+b
    a3=a+b+c
    a4=b+c+d
    a5=c+d+e
    a6=d+e+f
    a7=e+f
    a8=f
    a1+a4+a7 = a+b+c+d+e+f
    a2+a5+a8 = a+b+c+d+e+f
    a3+a6    = a+b+c+d+e+f不过 由<3>推出  <1>,要在有负数的情况下才成立,例如(2,2,1,1,1,2)÷(1,1,1)=(2,-1,2)由此可以得到一个特殊的情况下的算法:把 a1,a2,a3,…,an 平均分成 3 份,(如果n不能被3整除,则有1或2份多1个数),使每份的数的和相等,则a1,a2,a3,…,an可以在Σa /3 次内取完。不过大多数列是满足不了这个要求的,比如楼上讨论多的(3,5,6,4,7,7,6)
    a1+a4+a7=3+4+6 = 13
    a2+a5   =5+7   = 12
    a3+a6   =6+7   = 12所以一般情况下:(a1,a2,a3,…,an)经(1,1,1)尽量取后,会留有“余数”:
    情况1:余数是(……,0,x,y,……),假设 x<y,则要先取x次(0,1,1)再取y-x次(0,0,1)
    情况2:余数是(……,x,0,y,……),假设 x<y,则要先取x次(1,0,1)再取y-x次(0,0,1)
    其余情况类推偶现在就想到这么多,后面的推理我以后有空再来。找周公去也!