[英]Representing an positive integer as a sum of three numbers
In how many ways the positive integer n
can be represented as the sum of three different positive integers.正整数
n
可以用多少种方式表示为三个不同正整数的和。 The two methods are different if one contains a number that the other does not.如果一种方法包含另一个不包含的数字,则这两种方法是不同的。
I've managed to get the following script to count the number of ways to write n
as a sum of three numbers, but it's not takin the other condition in consiredation.我已经设法获得以下脚本来计算将
n
写为三个数字之和的方法的数量,但它并没有考虑其他条件。
def nways(n):
if (n <= 2):
return False
else:
ways = (n - 1) * (n - 2) / 2
return ways
For example if n = 8 I would need to return 2 since 1 + 2 + 5 = 8 and 1 + 3 + 4 = 8, but the current function returns 21...例如,如果 n = 8 我需要返回 2,因为 1 + 2 + 5 = 8 和 1 + 3 + 4 = 8,但当前函数返回 21...
What would be the correct algorithm and math behind this?这背后的正确算法和数学是什么?
def nways(n):
nways = 0
for i in range(1, n-2):
min_j, max_j = i+1, (n-i-1)//2
nways += (max_j - min_j + 1) if max_j >= min_j else 0
return nways
This algorithm consumes O(N)
time and O(1)
space.该算法消耗
O(N)
时间和O(1)
空间。
Let's denote the three positive numbers as i
, j
, k
.让我们将三个正数表示为
i
, j
, k
。
And since they are all different, these three numbers must be greater than or smaller than each other.而且由于它们都不同,因此这三个数字必须大于或小于彼此。 We assume the smallest number to be
i
, the middle one to be j
, the largest to be k
.我们假设最小的数字是
i
,中间的数字是j
,最大的数字是k
。 So then the relation would be i < j < k
.那么关系将是
i < j < k
。
Take n = 18
for example以
n = 18
为例
i = 1
, then j + k
should be 17
.i = 1
开始,那么j + k
应该是17
。
(j,k)
could be from (2,12)
, (3,14)
, ... to (8,9)
.(j,k)
可以从(2,12)
, (3,14)
, ... 到(8,9)
。(j,k)
couldn't be (9,8)
, (10,7)
because j<k
(j,k)
不能是(9,8)
, (10,7)
因为j<k
min_j
would be i+1
(in this case 2
), max_j
would be (ni-1)//2
(in this case 8
)min_j
将是i+1
(在这种情况下2
), max_j
将是(ni-1)//2
(在这种情况下8
)(j, k)
combinations are max_j - min_j + 1
which is 7
pairs in this case (j, k)
组合的数量是max_j - min_j + 1
,在这种情况下是7
对i = 2
, then j + k
should be 16
.i = 2
,那么j + k
应该是16
。
min_j
would be i+1
(in this case 3
), max_j
would be (ni-1)//2
(in this case 7
) min_j
将是i+1
(在这种情况下3
), max_j
将是(ni-1)//2
(在这种情况下7
)(j, k)
combinations are max_j - min_j + 1
which is 5
pairs in this case (j, k)
组合的数量是max_j - min_j + 1
,在这种情况下是5
对We try all the possible values of i
then add up all the combinations of (j, k)
pair, then we get the answer.我们尝试
i
所有可能值,然后将(j, k)
对的所有组合相加,然后我们得到答案。
You could use brute-force, with some more works:你可以使用蛮力,还有一些工作:
def ways(n):
tuple_sum_set = set()
for i in range(1, n+1):
for j in range(1, n+1):
for k in range(1, n+1):
if i + j + k == n and len(set([i, j, k])) == 3:
tuple_sum_set.add(tuple(sorted([i,j,k])))
print(tuple_sum_set)
return len(tuple_sum_set)
print(ways(8))
Demo: https://repl.it/repls/ChocolateHelplessLivecd演示: https : //repl.it/repls/ChocolateHelplessLivecd
A very different approach would be to use a constraint solver.一种非常不同的方法是使用约束求解器。 Here is an example:
下面是一个例子:
import constraint as con
n = 8
p = con.Problem()
p.addVariables(['x','y','z'],range(1,n-2))
p.addConstraint(con.ExactSumConstraint(n))
p.addConstraint(lambda a, b, c : a < b < c, ("x", "y", "z"))
sols = p.getSolutions()
print(len(sols))
sols
This gives:这给出:
2
[{'x': 1, 'y': 3, 'z': 4}, {'x': 1, 'y': 2, 'z': 5}]
I am not aware of a simple formula that predicts the number of solutions.我不知道预测解决方案数量的简单公式。
You can make some pretty significant optimizations to @hgb123's already great answer to still use brute-force, but be a little more clever about it:您可以对@hgb123 已经很好的答案进行一些非常重要的优化,以仍然使用蛮力,但要更聪明一点:
def ways(n):
tuple_sum_set = set()
for i in range(1, n-2):
for j in range(i+1, n-2):
for k in range(j+1, n-2):
if i + j + k == n:
tuple_sum_set.add((i,j,k))
print(tuple_sum_set)
return len(tuple_sum_set)
(If you up-vote this answer, please up-vote @hgb123's as well as this is a derivative of his answer) (如果您对这个答案投赞成票,请投给@hgb123 以及这是他的回答的衍生物)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.