Any number can be represented as a sum of square of numbers, for example 9 can be represented as 3 2 or 2 2 + 2 2 + 1 2 or even 9 t i m e s 1 2 + 1 2 + ⋯ + 1 2 .
Let ς ( n ) be the minimum squares of numbers needed in the representation of n . What is the value of.. i = 2 ∑ 2 0 1 5 ς ( i )
Details and assumptions
As explicit examples:
ς ( 1 0 0 ) = 1 ⟶ 1 0 2
ς ( 1 2 0 ) = 3 ⟶ 1 0 2 + 4 2 + 2 2
This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try
refreshing the page, (b) enabling javascript if it is disabled on your browser and,
finally, (c)
loading the
non-javascript version of this page
. We're sorry about the hassle.
What is the time complexity for your number-theoretical approach? I based only on Lagrange's four-square theorem without any optimization and I think the time complexity is O ( N N ) .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Log in to reply
Since you use three nested loops that count up to N , I would think that the complexity of O ( N N ) is correct.
My first approach has complexity O ( N 2 ) , although for the given value N = 2 0 1 6 it is not significantly slower. For much higher values of N , I would maintain a list of squares, which requires slightly more coding and reduces the complexity to O ( N N ) .
The complexity of my second approach depends on the complexity of finding a prime factorization for a given number between 1 and N .
Log in to reply
Here is my solution with complexity O ( N N ) :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
If n − 1 can be written as the sum of s s squares, then n can be written as the sum of s s + 1 squares. That is the initial guess.
Next we loop through all squares k 2 ≤ n to see if n k = n − k 2 is a better starting point. Note the trick I used to reduce the arithmetic to additions and subtractions only.
Log in to reply
@Arjen Vreugdenhil
–
This is a much better
O
(
N
N
)
, and
nk-= k, k++, nk-= k
is a very neat trick! For those who are wondering, it's due to the fact that
n
2
−
(
n
−
1
)
2
=
2
n
−
1
What about this approach:
`
import math
Min=[1,2,3]
def MIN(n):
kmins=[]
if math.floor(n**0.5) == math.ceil(n**0.5) and (n not in Min):
Min.append(1)
else:
for i in range(int(math.floor(n**0.5)),1,-1):
m=n-(i**2)
kmins.append(Min[m-1]+1)
if len(kmins)!=0:
Min.append(min(kmins))
for n in range(4,2015):
MIN(n)
print sum(Min) -1
`
Sorry for the bad formatting .But can anyone explain why my code is incorrect?
I keep getting 5710 instead of 5714?
Thanks!!!
Log in to reply
The condition 'and (n not in Min)' is meaningless. It appears that it does not harm. Likewise, if the condition 'if len(kmins)!=0' is ever false (which won't happen), your program will no longer work, since the number of squares needed for m is no longer at position Min[m-1]. Still, that does not explain why you get 5710...
Log in to reply
Thank you!!!,I agree a very stupid error on my part concerning the limit to which the loop had to be run,I guess I was too tired to notice it,I put the limit as 2016 and it worked! And also yeah the 'and (n not in Min)' is useless .Also the condition for len(kmins) is needed because when the number is a perfect square kmins is of zero length. Thanks again appreciate the help.
Log in to reply
@Arkin Dharawat – If you keep the append command within the 'else' block, the condition is not needed, because perfect squares are not dealt with in the 'else' block.
If I remember correctly, the range function in Python counts up to but not including the second number.
The "for i in range(...)" is affected by this only if n <= 3, and you pre-programmed those into your Min list.
But the "for n in range(4, 2015)" now only runs up to 2014. And 2015 is the sum of four squares, since it yields a remainder of 7 modulo 8. This explains the discrepancy!
Hello Sir. I'm sorry to disturb you Sir, but I've run into a problem with the program I wrote which seems impossible for me to understand. I would be really grateful if you could kindly tell me what is wrong with the code.
Sir, I've tried to solve this first without using Dynamic Programming and had devised the following code. However, the code keeps returning the answer as 7609.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
cout<<s<<" "<<count<<endl;
This is to display the number and show the minimum number of squares which need to be added. I added this line to check if the code was working for some randomly selected numbers (eg 120 did indeed return a value of 3).
cout<<sc;
This is the sum of the individual count(s).
1 2 3 4 5 |
|
I created this fragment of code primarily for the numbers 2 and 3 . In my original code,the moment any square number m was used, m was decreased immediately by 1. However, this didn't work for 2 or 3. Thus (considering 2) because initially m was equal to 2. Since 2 is not a perfect square, I reduced the value of m by 1 ie m = 1 after the decrement.
Now, in the original code, the new value of m (=1) was used, the value of m was decreased by 1. To counter this, I modified the code so that while the maximum square number m was smaller than or equal to i (and its subsequent modified values), it would keep getting subtracted from i . Only once this condition was violated would the value of , be decreased.
Many many thanks in anticipation!
PS. The original code was almost identical except that the value of m was reduced by 1 after each use. The part of the code referred top was as follows:
1 2 3 4 5 6 7 8 9 |
|
Log in to reply
If I understand your approach correctly, you start by subtracting the largest square possible. Your algorithm is too "greedy". For instance, if s = 1 8 , your program will think of it as 1 8 = 4 2 + 1 2 + 1 2 , and fails to see that it may be written as 1 8 = 3 2 + 3 2 .
Log in to reply
Thank you Sir. Sir, I realized this just now considering the case of 2 3 (my algorithm return a value of 5 whereas the answer seems to be 4). Sir, please could you show me how to modify my algorithm?
Log in to reply
@User 123 – Using the ideas of dynamic programming, you want to maintain an array of the results for smaller numbers.
Then, for each number n you consider every square m 2 ≤ n , look up the number of squares needed for n − m 2 and add one. Of all these numbers, you choose the lowest.
For instance, for n = 1 8 , your table will look like this (starting at 1): 1 , 2 , 3 , 1 , 2 , 3 , 4 , 2 , 1 , 2 , 3 , 3 , 2 , 3 , 4 , 1 , 2 . Now we try m 2 = 1 6 m 2 = 9 m 2 = 4 m 2 = 1 n − m 2 = 2 n − m 2 = 7 n − m 2 = 1 2 n − m 2 = 1 7 2 + 1 = 3 1 + 1 = 2 3 + 1 = 4 2 + 1 = 3 1 8 = 4 2 + ( 1 2 + 1 2 ) 1 8 = 3 2 + ( 3 2 ) 1 8 = 2 2 + ( 2 2 + 2 2 + 2 2 ) 1 8 = 1 2 + ( 1 6 2 + 1 2 )
To speed up your algorithm, here are some suggestions:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
@Arjen Vreugdenhil Sir, please could you help me?
Here's a C++ solution using Dynamic Programming:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
Output:
1 |
|
Notice that ς ( n ) = m i n { 1 + ς ( n − i 2 ) } f o r i ≤ ⌊ n 0 . 5 ⌋ . This recurrence can then be used to build a bottom up Dynamic Programming approach.
Python 2.7
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Nice usage of dynamic programming here to simplify the calculations slightly. It is naturally motivated from the way in which we want to find the value as a sum of (smaller) squares.
A variant of the solution in python 3.4:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
First of all, observe that by Lagrange's Four Square Theorem , ς ( n ) ≤ 4 , ∀ n . Hence we have to just check up to 3 combinations of squares of all numbers in the list { 1 , 2 , … , ⌊ N ⌋ } where N = 2 0 1 5 . Computational complexity Θ ( N 1 . 5 ) .
Yay to number theoretic approaches! Let's continue in this vein.
In fact, we can easily classify the numbers which need 1 square (perfect squares), those which need (at most) 2 square (via Fermat's two square theorem) and those which need (at most) 3 squares (via Legendre 3 square theorem).
Log in to reply
Number-theoretical approach added to my original solution.
Log in to reply
Could you add that to your solution? Thanks!!
I do not get this solution. How would you check up to three combinations?
Problem Loading...
Note Loading...
Set Loading...
The answer is 5714.
Here is a dynamic-programming approach. In an array a[i] we keep track of the number of ways in which a number can be written as the sum of squares. Starting with "1" for the perfect squares, we then combine each number with subsequent numbers to generate further possibilities.
A number-theoretical approach: