我最近在我的停机时间一直在玩HackerRank,并且在解决这个问题时遇到了一些麻烦:https://www.hackerrank.com/challenges/functional-programming-the-sums-of-powers有效率。
问题陈述:给定两个整数 X 和 N ,找出表达X
的总和的方式的数量N
唯一自然数的幂。
示例: X = 10, N = 2
只有一种方法可以使用10以下 2 的权力获得10,那就是1^2 + 3^2
我的方法
我知道这个问题可能存在一个很好的,优雅的复发;但不幸的是我找不到一个,所以我开始考虑其他方法。我决定从[1,Z]
收集一系列数字,其中 Z 是 X 的最大数字,当它被提升到名词的。因此,对于上面的示例,我只考虑[1,2,3]
,因为4^2 > 10
因此不能成为总数为10的(正)数字的一部分。收集这些数字后,我将它们全部提升到power N 然后找到该列表的所有子集的排列。因此对于[1,2,3]
我发现了[[1],[4],[9],[1,4],[1,9],[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()))
}
}
以前有人遇到过这个问题吗?如果是这样,有更优雅的解决方案吗?
答案 0 :(得分:0)
在您构建了正方形列表之后,我会考虑将Partition Problem称为Subset Sum Problem的{{3}}。这是一个旧的NP-Complete问题。所以第一个问题的答案是“是”,第二个问题的答案在链接中给出。
答案 1 :(得分:0)
这可以被认为是动态编程问题。我仍然迫切需要动态编程问题,因为这就是我的教学方法,但这可能是有用的。
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]
通过跟踪哪些指数是非平凡的,但效率不是那么高,可以略微提高效率。
答案 2 :(得分:0)
class Calculation {
protected $a;
protected $b;
protected $c;
public function __construct() {
;
}
public function setA($a) {
$this->a = $a;
}
public function setB($b) {
$this->b = $b;
}
public function call() {
$this->c = (int) $this->a + (int) $this->b;
}
public function getC() {
return $this->c;
}
}