Last Sunday, I had a $50 food coupon.
With it I could buy items from the canteen which costs at most $50.
I saw that I was so hungry that I had to buy exactly 5 items from the canteen.
However, the canteen had a strange rule. They partitioned their list of items in 2-tuples. You can only order at most one item from each tuple.
If the following is the list of the items labelled 'A' thru 'T' with the tuples contained in braces, in how many ways can I order the items?
1 2 3 4 5 6 7 8 9 10 |
|
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 the numbers be labelled as a 1 , a 2 , b 1 , b 2 , … j 1 , j 2 .
Consider the polynomial ∏ ( 1 + x k 1 y + x k 2 y ) .
Then, the conditions tell us that we are interested in the sum of coefficients of the terms x k y 5 where 0 ≤ k ≤ 5 0 . This is ugly, but easily computed.
We get that the answer is 4957.
A follow up question is, what approach has the least complexity / shortest run time as the number of lines approach infinity? My approach has an exponential run-time, though it's quite easy to understand and code up.
Dynamic programming. Let P [ i ] [ k ] [ b ] be the number of ways to choose k items from the first i tuples that cost exactly b . Then, P [ 0 ] [ 0 ] [ 0 ] = 1 and P [ i ] [ k ] [ b ] = P [ i − 1 ] [ k ] [ b ] j ∑ P [ i − 1 ] [ k − 1 ] [ b − A [ i ] [ j ] ] if the items in the i -th tuple have costs A [ i ] [ ] . (The reason why this holds is quite clear: we either chose an item from the i -th tuple or not; if we chose an item, the cost of all k − 1 items chosen before it is b − A [ i ] [ j ] .)
Complexity: O ( N K B ) if there are N items in T tuples, out of which we need to choose K and the budget is B , which is (pseudo)polynomial; the answer is ∑ b P [ T ] [ K ] [ b ] .
By ∏ ( 1 + x a 1 y + x a 2 y ) , do you mean ( 1 + x a 1 y + x a 2 y ) ( 1 + x b 1 y + x b 2 y ) ( 1 + x c 1 y + x c 2 y ) ⋯ ( 1 + x j 1 y + x j 2 y )
Log in to reply
Yupz. I ran out of variables to use. Changed it to k 1 , k 2 and hopefully that makes more sense.
Though this approach is easy to understand, it get pretty tedious (even after working modulo x 5 0 , y 5 .
This is great! Pretty much what @bobbym none did, when Nick asked him the same question here
This is the code I ran, which gives me 9676686 as the answer. I don't know what's wrong with it. Anyone can help me? Thanks.
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
|
Mathematica:
1 2 3 4 5 |
|
Haskell:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
I updated the image. Is this more suitable?
Log in to reply
Log in to reply
Got it. :)
This took me like three hours to solve. Cool problem.
Nice short Mathematica solution, I wrote mine in Python and I still had to use 48 lines. The Haskell solution gave me a good laugh.
Using brute force (code written in Boo):
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 33 34 35 36 37 38 39 40 |
|
I use Python to quote.
# Kaboobly Dooists visit the Canteen
from itertools import combinations
L=[[12,7],[10,9],[7,13],[11,9],[8,13],[10,10],[8,11],[11,9],[7,11],[9,12]]
s = []; a = []; b = []; c = []; d = []; e = []
n = 0
for p in combinations("0123456789",5):
a = L[int(p[0])]
b = L[int(p[1])]
c = L[int(p[2])]
d = L[int(p[3])]
e = L[int(p[4])]
for i in range (2):
for j in range (2):
for k in range (2):
for l in range (2):
for m in range (2):
t = a[i]+b[j]+c[k]+d[l]+e[m]
if t <= 50:
n += 1
print n, t, a[i], b[j], c[k], d[l], e[m]
Calvin Lin But how do you go about doing this?
I did it using binary numbers. Binary numbers will give us all combinations of 1s and 0s. This property can be exploited to go through all the combinations in an orderly fashion. I only know C++ language, so I had to make up a lot of things for the implementation. I do not know how fast it runs. But it seems to run within a second or so.
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
|
I am really interested in programming and CS. But the algorithms and methods used by many to solve problems here are way too hard for me to understand. Is there a way to learn these things easily? Any suggestions Agnishom Chattopadhyay ?
@Calvin Lin @Agnishom Chattopadhyay
Log in to reply
Solve a lot of computer science problems. Also, solve a lot of problems in the computer science way. If possible, think of various ideas. Also, read through the solutions. You might want to try Project Euler, Hacker Rank, CodeChef, etc for cool programming problems.
Try analysing your code. Think why it is correct and how fast it runs. Think how it can be improved.
Assign yourself nice projects like maybe creating a game or an android app or a sudoku solver or a cool animation. That way you get better with coding.
Do not expect there to be comprehensive compact tutorials for every useful algorithm. Be desperate to code out ideas you see around.
If there is anything I can help you with, post a note and tag me
Log in to reply
Thank you so much! Really appreciate the help!
Problem Loading...
Note Loading...
Set Loading...
This looks like a job for breadth first search !
Python:
Evaluation time: 2.98 seconds