使用动态编程解决附加链问题

时间:2012-05-04 07:02:00

标签: algorithm dynamic-programming

给出一个正整数A.目标是使用以下规则构造以A结尾的最短可能整数序列:

  1. 序列的第一个元素是1
  2. 每个连续元素是前两个元素的总和(也允许向自身添加单个元素)
  3. 每个元素都大于前面的所有元素;也就是说,序列正在增加。
  4. For example, for A = 42, a possible solutions is [1, 2, 3, 6, 12, 24, 30, 42]. Another possible solution is [1, 2, 4, 5, 8, 16, 21, 42].

    在阅读问题陈述之后,我首先想到的是Dynamic Programming,因此我将上述内容表达为搜索问题并尝试为其编写递归解决方案。

    搜索空间:

                    1
                    |
                    2
                   / \
                  /   \            
                 3     4
                /|\   /|\
               / | \ 5 6 8
              /  |  \
             4   5   6
           /| |\  
          5 6 7 8
    

    现在我们可以看到4个发生在两个地方,但在这两种情况下,4个孩子都是不同的,因为在一个案例中,sequence_so_far是[1,2,4],在另一个例子中它是[1,2] ,3,4],因此我们不能说我们有重叠的子问题。有没有办法将动态编程应用于上述问题?或者我判断使用DP可以解决它是错误的吗?

3 个答案:

答案 0 :(得分:2)

这是附加链 ...

http://en.wikipedia.org/wiki/Addition_chain

  

没有可以计算a的已知算法   对于给定数字的最小附加链,具有任何保证   合理的时间或小内存使用。但是,有几种技术   计算相对较短的链条存在。一个众所周知的   计算相对较短的加法链的技术是二进制   方法,类似于通过平方取幂。其他知名人士   方法是因子方法窗口方法

生成短加法链的新方法

http://it29.it.k.u-tokyo.ac.jp/pdfs/E83-A-1-60.pdf

答案 1 :(得分:1)

这个问题有一个纯粹的动态编程解决方案。但是作为所有DP解决方案,内存和时间的复杂性都是N平方。所以它可以是太空猪。但这里只是DP爱好者的DP解决方案的关键:

概括:

而不是找到N的最小加法链长度。 l(N),我们要找到包含i和j的加法链的最小长度,其中i≤j且j在链中是max。将此长度称为A(i,j)。显然,我们有

  1. 1(N)= A(1,N)= A(N,N)
  2. A(1,N)= A(2,N),如果N≥2
  3. A(1,N)= 1 + min(A(i,j),1≤i≤j

    提前计算

    要使用较小的A(i,j)(典型的DP步骤)计算任何A(m,n),我们应用一些启发式算法。

    H1:沿途保持(3)的最小部分的S(i + j)。然后

     A(1, n) = A(2, n) = A(n, n) = S(n)+1
    

    对于其他m,我们通过向链中引入最多一个新元素来减少n,并且使用这样一个新元素,我们只需要再做一步来得出A(m,n)。可能性

    H2:如果n是偶数,我们尝试将n / 2引入链中 H3:尝试将n-m引入链中 H4:尝试将n-1引入链中 H5:尝试将n-2引入链中(当n> 2时)

    所以A(m,n)取m的最小值和基于H2-H5的减少的n加1。

    实施例,A(52,100)= 1 + min(A(50,52),A(48,52),A(52,99),A(52,98)分别应用H2-H5

答案 2 :(得分:-1)

由于规则#2,

  

每个连续元素是任何前两个元素的总和

该算法确实依赖于重复的子问题,因此动态编程适合于解决它。

相关问题