Algorithm 将自然数表示为不同平方和

Algorithm 将自然数表示为不同平方和,algorithm,number-theory,Algorithm,Number Theory,问题是找到正整数的最大集合S,使得S元素的平方和等于给定的数字n 例如: 4=2² 20=4²+2² 38=5²+3²+2² 300=11²+8²+7²+6²+4²+3²+2²+1² 我有一个在时间O(2^(sqrt n)*n)中运行的算法,但是它太慢了(每个正方形的子集)。有一个O(n^1.5)-时间算法,基于标准的动态程序。以下是重复出现的情况: C(m, k) is the size of the largest subset of 1..k whose squares sum to m

问题是找到正整数的最大集合S,使得S元素的平方和等于给定的数字n

例如:

4=2²
20=4²+2²
38=5²+3²+2²
300=11²+8²+7²+6²+4²+3²+2²+1²

我有一个在时间
O(2^(sqrt n)*n)
中运行的算法,但是它太慢了(每个正方形的子集)。

有一个
O(n^1.5)
-时间算法,基于标准的动态程序。以下是重复出现的情况:

C(m, k) is the size of the largest subset of 1..k whose squares sum to m
C(m, k), m < 0 = -infinity (infeasible)
C(0, k) = 0
C(m, 0), m > 0 = -infinity (infeasible)
C(m, k), m > 0, k > 0 = max(C(m, k-1), C(m - k^2, k-1) + 1)
T(0, m) = 0
T(n, m) = -Infinity (if n<0 or m<0)
T(n, m) = max(T(n-m*m, m-1)+1, T(n, m-1))
C(m,k)是1..k的最大子集的大小,其平方和为m
C(m,k),m<0=-无穷大(不可行)
C(0,k)=0
C(m,0),m>0=-无穷大(不可行)
C(m,k),m>0,k>0=max(C(m,k-1),C(m-k^2,k-1)+1)

0..n
中的所有
m
0..floor(n^0.5)中的所有
k
计算
C(m,k)
。返回目标值的
C(n,下限(n^0.5))
。要恢复集合,请追溯argmaxes。

我只是想知道这个问题是否会归结为NP?看起来您的整数(平方)列表小于
n
(可以在
O(sqrt(n))
中生成),并且您正在查找从
1到sqrt(n)
的大小的子集和(检查所有可能性)。如果是这样的话,它应该可以用背包动态规划算法来解决(但这是一个非常幼稚的算法,我认为它可以改进)在
O(n^2)
-sqrt(n)的问题中检查次数sqrt(n)背包物品计数次数n背包重量

编辑:
我认为在填充动态编程数组后,使用智能回溯,您可以在
O(n*sqrt(n))
中执行回溯,您可以使用递归:

C(m, k) is the size of the largest subset of 1..k whose squares sum to m
C(m, k), m < 0 = -infinity (infeasible)
C(0, k) = 0
C(m, 0), m > 0 = -infinity (infeasible)
C(m, k), m > 0, k > 0 = max(C(m, k-1), C(m - k^2, k-1) + 1)
T(0, m) = 0
T(n, m) = -Infinity (if n<0 or m<0)
T(n, m) = max(T(n-m*m, m-1)+1, T(n, m-1))

所以问题是你想要一个更快的算法?不幸的是我的解决方案太慢了。你的问题不清楚,因为你根本没有提到。你给出的例子是错误的。300可以写成11²+8²+7²+6²+4²+3²+2²+1²。哎,你熟悉动态规划吗?你可以在任何一本好的算法书上读到。