Find the last 3 digits of the number of subsets (summing to 1 0 0 0 ) of the set of positive integers from 1 to 1 0 0 (both inclusive).
For example, the set:
{ 1 , 1 6 , 3 0 , 4 3 , 4 7 , 5 2 , 5 3 , 5 5 , 5 7 , 6 0 , 6 4 , 6 7 , 6 8 , 6 9 , 7 1 , 7 2 , 7 5 , 1 0 0 }
sums to 1 0 0 0 and it is a subset of the set of positive integers from 1 to 1 0 0 (inclusive), so it would be included.
Subsets do not have ordered elements and a subset can not contain repeats of elements.
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.
Let m be a positive integer. Define f ( n , m ) to be the number of subsets of { 1 , 2 , … , n } such that the sum of elements in the subset is m . Then I got the following recursive relation:
f ( n , 1 ) = 1 .
f ( 1 , m ) = 0 if m > 1 .
For m > 1 and n > 1 :
f ( n , m ) = f ( n − 1 , m ) + f ( n − 1 , m − n ) if m > n ,
f ( n , m ) = f ( n − 1 , m ) + 1 if m = n ,
f ( n , m ) = f ( n − 1 , m ) if m < n .
I wrote a C program (I don't know how to post the codes like you did above and I haven't programmed for long time), but it didn't end up with the answer you got (my answer is 413). I am not sure where it went wrong. [EDIT] OK, looks no need to do anything for the body of the main function. Somehow, it doesn't format correctly if includes everything.
long i, j;
long a[101][1001];
a[1][1] = 1;
for (i=2; i<=100; i++) {
a[i][1] = 1;
}
for (j=2; j<=1000; j++) {
a[1][j] = 0;
}
for (j=2; j<=1000; j++) {
for (i=2; i<=100; i++) {
if (j > i)
a[i][j] = (a[i-1][j] + a[i-1][j-i]) % 1000;
else if (j == i)
a[i][j] = a[i-1][j] + 1;
else
a[i][j] = a[i-1][j];
}
printf ("%d\t%d\t%d\n", i-1,j, a[i-1][j]);
}
633172672364586108413-5983373858461353469 = 2^64*34, so you indeed experienced overflow.
Log in to reply
So you are saying 413 is the correct answer instead of 469? Time to dispute.
Log in to reply
I got 413 as well through both a C++ program and an Excel program.
Log in to reply
@Crefin Baras – It is definitely 413. I used Mathematica 9 to double check. Wasted 3 hours on this...........
633172672364586108413, I am using maple...
The answer should be 413
I agree. This should be tagged with #ComputerScience
I wrote a simple C++ program to recursively compute the number of subsets knowing the last integer taken and the sum of all integers in the subset I'm matching.
To speed up the algorithm we can see that there are some sub-problems that we have to compute more than once: it's time to DP! We just have to save our results into a matrix and return them when necessary.
Time complexity O( N^3 ) where N is the number of starting elements.
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 |
|
Have a look at this
Replace the first two lines with:
Numbers=xrange(1,101)
Maximum=1000
And run the code!
There is a complete explanation in Stackoverflow
Problem Loading...
Note Loading...
Set Loading...
I had gotten 5 9 8 3 3 7 3 8 5 8 4 6 1 3 5 3 4 6 9 from using an array int64 variables instead of BigInteger variables to store intermediate solutions. I had also requested that this problem be tagged under #ComputerScience instead.
Since checking through all 2 1 0 0 subsets would take an impossibly long time (even for a standard computer), a faster approach is needed. The one which I came up with is inspired by generating functions. More specifically, the number of subsets which sum to 1 0 0 0 is given by the coefficient of x 1 0 0 0 in the product i = 1 ∏ 1 0 0 ( 1 + x i ) . I will not explain this here, but this is the basis for the solution shown here.
For every element k in the set of integers from 1 to 1 0 0 inclusive, k is either included in a subset, or it is not. Therefore, if there is already a running list of the number of subsets which sum to a particular value, it is possible to add on the subsets which include k to the running list. For example:
Starting:
Subsets with sum 0 : 1
k = 1 :
Subsets with sum 0 : 1
Subsets with sum 1 : 0 + 1 = 1
k = 2 :
Subsets with sum 0 : 1
Subsets with sum 1 : 1
Subsets with sum 2 : 0 + 1 = 1
Subsets with sum 3 : 0 + 1 = 1
k = 3 :
Subsets with sum 0 : 1
Subsets with sum 1 : 1
Subsets with sum 2 : 1
Subsets with sum 3 : 1 + 1 = 2
Subsets with sum 4 : 0 + 1 = 1
Subsets with sum 5 : 0 + 1 = 1
Subsets with sum 6 : 0 + 1 = 1
k = 4 :
Subsets with sum 0 : 1
Subsets with sum 1 : 1
Subsets with sum 2 : 1
Subsets with sum 3 : 2
Subsets with sum 4 : 1 + 1 = 2
Subsets with sum 5 : 1 + 1 = 2
Subsets with sum 6 : 1 + 1 = 2
Subsets with sum 7 : 0 + 2 = 2
Subsets with sum 8 : 0 + 1 = 1
Subsets with sum 9 : 0 + 1 = 1
Subsets with sum 1 0 : 0 + 1 = 1
Continuing the pattern up to 1 0 0 gives that the number of subsets is 6 3 3 1 7 2 6 7 2 3 6 4 5 8 6 1 0 8 4 1 3 . Another possible optimization is only storing the values mod 1 0 0 0 , since not only the answer will be in a more convenient form, but if using a language like C++ or Java, 16 or 32 bit integers will suffice instead of the otherwise required BigIntegers.
Here is a snippet of code from my Java solution: