Scala 将X表示为唯一自然数的n次幂之和

Scala 将X表示为唯一自然数的n次幂之和,scala,combinatorics,number-theory,Scala,Combinatorics,Number Theory,我最近在休息时间一直在玩HackerRank,在解决这个问题时遇到了一些困难:效率 问题陈述:给定两个整数X和N,找出将X表示为唯一自然数的N幂和的方法数 示例:X=10,N=2 只有一种方法可以使用低于10的2的幂得到10,那就是1^2+3^2 我的方法 我知道这个问题可能存在一个很好的、优雅的反复出现;但不幸的是我找不到,所以我开始考虑其他方法。我决定从“代码> [1,Z] ,因为 4 ^ 2>10 < /代码>,因此不能是总和为10的(正)数的一部分。在收集了这一系列的数字之后,我把它们都

我最近在休息时间一直在玩HackerRank,在解决这个问题时遇到了一些困难:效率

问题陈述:给定两个整数X和N,找出将
X
表示为唯一自然数的
N
幂和的方法数

示例:X=10,N=2

只有一种方法可以使用低于10的2的幂得到10,那就是
1^2+3^2

我的方法

我知道这个问题可能存在一个很好的、优雅的反复出现;但不幸的是我找不到,所以我开始考虑其他方法。我决定从“代码> [1,Z] [1,2,3] < /COD>,因为<代码> 4 ^ 2>10 < /代码>,因此不能是总和为10的(正)数的一部分。在收集了这一系列的数字之后,我把它们都提升到N的幂,然后找到了这个列表中所有子集的排列。所以对于
[1,2,3]
我发现
[[1],[4],[9],[1,4],[1,9],[4,9],[1,4,9],[1,4,9]
,对于较大的初始数字范围,这不是一系列简单的操作(我的解决方案在最后两次黑客测试中超时)。最后一步是计算总计为X的子列表

解决方案

object Solution {
    def numberOfWays(X : Int, N : Int) : Int = {
        def candidates(num : Int) : List[List[Int]] = {
            if( Math.pow(num, N).toInt > X ) 
                List.range(1, num).map(
                    l => Math.pow(l, N).toInt
                ).toSet[Int].subsets.map(_.toList).toList
            else 
                candidates(num+1)
        }
        candidates(1).count(l => l.sum == X)
    }

    def main(args: Array[String]) {
       println(numberOfWays(readInt(),readInt()))
    }
}

以前有人遇到过这个问题吗?如果是这样,还有更优雅的解决方案吗这可以看作是一个动态规划问题。我仍然有必要对动态规划问题进行推理,因为我就是这样被教导的,但这可能是功能性的

A.  Make an array A of length X with type parameter Integer.
B.  Iterate over i from 1 to Nth root of X.  For all i, set A[i^N - 1] = 1.
C.  Iterate over j from 0 until X.  In an inner loop, iterate over k from 0 to (X + 1) / 2.
    A[j] += A[k] * A[x - k]
D.  A[X - 1]
通过跟踪哪些索引是非平凡的,可以稍微提高效率,但效率并没有那么高。

def numberOfWays(X:Int,N:Int):Int={
def numberOfWays(X: Int, N: Int): Int = {

    def powerSumHelper(sum: Int, maximum: Int): Int = sum match {
      case x if x < 1 => 0
      case _ => {
        val limit = scala.math.min(maximum, scala.math.floor(scala.math.pow(sum, 1.0 / N)).toInt)
        (limit to 1 by -1).map(x => {
          val y = scala.math.pow(x, N).toInt
          if (y == sum) 1 else powerSumHelper(sum - y, x - 1)
        }).sum
      }
    }

    powerSumHelper(X, Integer.MAX_VALUE)
  }
def powerSumHelper(总和:整数,最大值:整数):整数=总和匹配{ 如果x<1=>0,则为情况x 案例=>{ val limit=scala.math.min(最大值,scala.math.floor(scala.math.pow(总和,1.0/N)).toInt) (限制为1乘-1)。映射(x=>{ valy=scala.math.pow(x,N).toInt if(y==sum)1 else powerSumHelper(sum-y,x-1) }).sum } } powerSumHelper(X,整数.MAX_值) }