Number of ways to pick at least x balls (balls are identical)? - python-2.7

There are N distinct boxes of balls in total. There are P boxes each containing A number of balls and remaining Q boxes contains B number of balls each.
Given a number X, what are the total the number of ways in which you can pick at least X balls from the boxes.
P+Q = N
Example: Number of P boxes=2 which contain 2 balls each, Number of Q boxes=1 which contain 2 balls. X=3(Given) where x=minimum number of balls to be picked
So, P+Q=3 (total number of boxes)
Combinations for the number of ways to pick atleast x i.e. 3 balls would be:
combinations of 3:(111),(210),(120),(021),(012),(201),(102)
combinations of 4:(220)(202)(022)(211)(121)(112)
combinations of 5:(212)(122)(221)
combinations of 6: (222)
total Combinations: 17
My Approach:
I have used "Stars and Bars Approach":
To calculate combinations of 6: x+y+z=6 which is converted into (2-x)+(2-y)+(2-z)=6 giving out x+y+z=0.
So, the combination of 6 becomes Binomial(2C2)=1
Similarly, Combinations of 5 becomes Binomial(3C2)=3
Combinations of 4= Binomial(4C2)=6
Combinations of 3= Binomial(5C2)=10
1+3+6+10=20
but the answer should be 1+3+6+7=17
Edge case has appeared on calculating the combinations of 3. How should I tackle this problem?
EDIT: CODE ADDED in python
global total_combinations
total_combinations=0
from math import factorial
def combinations(a):
global total_combinations
bars=numberofAs+numberofBs-1
stars=a
total_combinations+=factorial(stars+bars)/(factorial(bars)*factorial(stars))
numberofAs,numberofBs,numberofballsinA,numberofballsinB=map(int,raw_input().split())
x=int(raw_input())
operational_array=[]
for i in range(numberofAs):
operational_array.append(numberofballsinA)
for i in range(numberofBs):
operational_array.append(numberofballsinB)
max_x=sum(operational_array) #calculate combinations from x to max_x
k=max_x
for i in range(max_x,x-1,-1):
k=max_x-i
combinations(k)
print total_combinations

The number of balls you can take out of a box containing A balls is the number of balls you can put into an empty box of capacity A.
There are known formulas for that problem.
If all boxes have the same number of balls initially (as in the given example, in which A=B=2),
and that number is equal to or greater than the total number of balls to be removed from the boxes, then "stars and bars" will work.
But if the number of balls to be removed is greater than the number in a single box, there is an iterative formula to find the number of ways the balls can be selected.
To remove t balls from k boxes containing m balls each,
from scipy.special import comb
def combinations_with_limit(t, k, m):
total = 0
max_full_boxes = min(k, int(t/(m + 1)))
for i in range(max_full_boxes + 1):
total += int((-1)**i) * comb(k, i, exact=True) * comb(t + k - 1 - i*(m + 1), k - 1, exact=True)
return total
This is based on the formula in this math.stackexchange answer, but using t rather than n for the total number of balls removed in order to avoid confusion with the use of N in this question.
You can optimize and improve the style of this code, of course
(for example, I wouldn't suggest writing int((-1)**i) in production code);
the reason it's written this way is to stay as close as practical to the format of the MSE answer.
Not surprisingly, we have to think a little harder in the case where A and B are different.
To remove a total of t balls from p boxes containing a balls each and q boxes containing b balls each,
def combinations_with_two_limits(t, p, q, a, b):
total = 0
min_balls_from_p = max(0, t - q*b)
max_balls_from_p = min(t, p*a)
for i in range(min_balls_from_p, max_balls_from_p + 1):
total += combinations_with_limit(i, p, a) * combinations_with_limit(t - i, q, b)
return total
The idea here is that you first decide how to allocate the t balls into two groups, one to be removed from the boxes containing a balls and the other to be removed from the boxes containing b balls,
and then count all the ways you can select those subsets of the balls from those subsets of the boxes.
It may be possible to optimize the code further by going back to the derivation of the MSE formula cited above (either through generating functions or the inclusion-exclusion principle), but I wouldn't try it unless it's really critical to shave a few percentage points off the running time.
To remove at least X balls from the boxes, take the sum of the values of
combinations_with_two_limits as t takes on all integer values from X up to and including the largest number of balls you can remove
(which is P*A + Q*B).

Break it in 2 parts where you pick k balls from the P boxes of capacity A and x-k balls from the Q bins with capacity B. Use stars and bars approach on each side to calculate the number of ways to pick k,x-k respectively, and multiply to get the total. (Considering of course that you can only do that when both k,x-k do not exceed the capacities A,B).
To not consider the cases where k>A and x-k>B you have to implement the formula below
Which counts all combinations in which n items are allocated to k bins, excluding combinations where at least one bin contains more than C items.
In your case you need to use this formula twice, once to allocate k balls to P bins with capacity A, and once to allocate x-k balls to Q bins with capacity B.
Then the multiplication should give you the correct result.

Related

How to calculate expected number of turns using DP in O(n)?

A single-player board game. The board is made up of a row of n cells numbered 1 to n from left to
right. Cell ‘j' contains a positive integer cj.
The rules are like this:
You start on the leftmost cell.
On each turn, you roll a fair 6-sided die with A as the outcome number. You
move forward A × cj cells, where j is the index of the cell that you are standing
on.
You win once you exit the board i.e., you win when your index j > n.
For instance, consider the board of size n=10
To begin with, you are at the first cell having the value c1 = 2. In the first turn, you roll a dice
and obtain a value 1, so you move forward 2 cells. Then on the next roll you roll a 5 on cell 3
(with c3 = 4), so you move forward 20 cells makes you exit the board. You win!! You took 2
turns to win.
How to calculate the expected number of turns needed to win using dynamic programming algorithm that runs in time (n) for the above game?
The recurrence relation you're looking for is:
E[j] = 0 (if j > n)
E[j] = 1 + 1/6 * sum_k(E[j + k * c_j]) (otherwise, for k \in 1..6)
For each cell, calculate how many turns to win on average.
For cell[k] with k>=n, this is 0.
For other cells with k<n, it 1 plus the average of turns to win at cell[1..6*c_k].
Cache results and don't recalculate them.
Return turns to win from cell 0.
Yes, this is seemingly nothing non-obvious. Dynamic programming is seeming to do nothing non-obvious, with an appropriately bounded cache in the middle of the naive algorithm.
The trick is arranging the problem to have a cache with good bounds that makes a naive algorithm collapse into not doing much work.

How to maximize the total probability?

I want to maximize the total probability of winning in a game of random selection which is played as follows,
I have n lottery tickets and out of these n only 1 is the lucky ticket, now I have 2 option either draw a ticket or ask the master to remove some X unlucky ticket out of total tickets, X must be a multiple of k (available) and X must be smaller than total number of tickets.
If i draw an unlucky ticket master will add k unlucky tickets to the pile of tickets.
We have at max m moves to play, each move is one of the following
Either we draw a ticket
Either we ask master to remove X tickets (X is multiple of k)
I want to maximize the probability.
And output the total probability P/Q as P*Q^(-1) where Q is modular inverse of Q.
After observing and playing the game I think the total probability will be maximum only when we play the game in the following way
First move we draw a ticket and probability of winning is 1/n.
If we draw an unlucky ticket in first move k tickets are added and we can ask the master to remove k tickets in second move.
In third move we again draw ticket and probability of winning now is
((n-1)/n)*(1/n) .
Similarly if there are m moves than we can conclude that, total probability of winning is (1-((n-1)/n)^r) where we can find value of r
n
for example :
n = 3 k = 20 m = 3
total probability is 1-(2/3)^2 = 5/9
n = 5 k = 7 m = 1
total probability of winning is = 1/5
Final output :
5*(9)^(-1) % 1000000007 = 555555560
1*(5)^(-1) % 1000000007 = 400000003
If there is other winning strategy in this game please provide it with proof and i don't have a proof for my strategy too so if you can prove my strategy i will be glad to have it as well as a psuedocode will help me to proceed.
we again put the ticket that we picked in the pile again so after drawing wrong we have n+k instead of n+k-1, and also n < k ( for the starting always)
EDIT : Proof of my strategy
for each move we take there are 2 possibilities
either we gain 1/n*(n-1)/n or we gain (n-1)/n*(1/n+k) + (n-1/n)((n+k-1)/n+k)(1/n+2*k)
now after solving both sides we get to equation 1/n left hand side and right hand side is (2*n+3*k-1)/((n+2*k)*(n+k) and i found that R.H.S is always less than or equals to R.H.S
So after further solving i get L.H.S as 2*(k^2) and R.H.S as n^2-n and as given n < k so L.H.S is always greater than R.H.s
Hence proved.
Please provide feedback for the proof.
Your strategy is incorrect. After drawing an unlucky ticket, you would ask the master to remove k tickets, but if you had started playing in exactly the same state, you would have picked a ticket instead. That does not make sense, because the game has no memory of your previous moves, and the present situation should therefore always dictate the best choice.
Let P(n,m,k) be the probability of winning with n tickets, max m moves, and k, with optimal strategy.
If you pick a ticket, then the probability is 1/n + P(n+k-1, m-1, k)*(n-1)/n.
If you don't then the probability is P(n-k, m-1, k)
The optimal choice is the one with best probability, and so:
P(n,m,k) = max( 1/n + P(n+k-1, m-1, k)*(n-1)/n , P(n-k, m-1, k) )
You can could calculate this recursively, with memoization since there are likely to be overlapping subproblems, i.e., with dynamic programming.

Fill the Grid with three colors A and B and C

How to find the numbers of ways to fill a grid (3*n)array, with three colors A, B and C.
Under the following constraints:
1) All the n cells of the same row can't have the same color.
2) All the 3 cells of the same column can't have the same color.
Sample input : if n=2, then output or number of ways = 174.
Please explain the approach for this.
This answer given by sam29 on codefores.
We can solve this question using Inclusion-Exclusion principle. So, let's first consider only the first column of the matrix. We can easily deduce that there are 24 different ways to fill that column keeping in mind that we can't have the same letter in the complete column. Now, we can directly say that the total ways to fill the complete matrix will be 24^N (Name this value as X1). In this answer, we have made sure that all the column contains distinct alphabets. But we need to consider the cases a row contains the same letter. So, now we will use inclusion-exclusion principle.
Find the number of cases with one row same. Fix 'A' in the first row. Now, take only the first column and you can deduce that there are 8 distinct ways to fill the 2nd and the 3rd row of the first column keeping in mind we can't have the same letter in the complete column. So, now we can find the total number of ways to fill all the N rows as 8^N. Now, we can do the same thing with 'B' and 'C' in the first row and similarly, we can repeat the process for the 2nd and the 3rd row. So, the total number of ways will be 9*8^N (Name this value as X2).
Find the number of cases with two rows same (Name this value as X3). This is the trickiest part of the question. I'll explain this at last.
Find the number of cases with all the three rows same but we can't have the same letter in a single column. This is pretty easy and is equivalent to the number of ways to fill a single column and 3 rows. So, the answer is 24 for this scenario (Name this value as X4).
Now, the final answer will be X1-X2+X3-X4.
Now, coming back to the answer for 2nd scenario. So, we will try to find the answer for the case when the first row and second row is same and we can repeat that process for the 2nd row and 3rd row AND 1st row and 3rd row. Basically, we can multiply the answer we will calculate now with 3. Okay, now take only the first column. Now, you can see that there will be 2 scenarios, one will be when the first and second row contains the same letter and in that case, we have to place a different letter in the 3rd row because else we will violate our condition of the distinct column. So, the total number of ways in the first scenario will be 3*2^N (I have skipped some part but I have provided the exact reason and a little further thinking and you will get the solution). Now, for the next scene when the first and second row contains different letters. In that case, you can place any letter in the 3rd row. Again try to think a little more and you will get the answer as 6*3^N. So, the total answer will be 3*2^N + 6*3^N. And as I said before we need to multiply it by 3 (Number of ways to choose 2 rows from 3 rows). So, X3 will be 3*(3*2^N + 6*3^N).
The complexity is pretty direct, you can do precomputation or apply exponent function every time.
Thanks.
This is combinatorial question, for sure it is better to post questions like this on math.stackexchange.com.
A row can be in two different configurations: having two colors (ABA) and having three colors (ABC). If we have last row of some configuration, lets check possibilities for next row.
A | B B B C C
B | A A C A A
A | B C B B C
A | B B B C
B | A C C A
C | B A B B
Set:
A_n : number of dimension n matrices where last row is of ABA configuration,
C_n : number of dimension n matrices where last row is of ABC configuration,
X_n : number of dimension n matrices = A_n + C_n.
From upper list of possibile next row it holds:
A_n = 3 * A_(n-1) + 2 * C_(n-1) = 2 * X_(n-1) + A_(n-1)
C_n = 2 * A_(n-1) + 2 * C_(n-1) = 2 * X_(n-1)
=>
X_n = 4 * X_(n-1) + A_(n-1)
Result to question is X_n, for which calculation A_n is needed, and initial values are A_1=6, X_1=12.
Update:
Search in OEIS for values 2, 9, 41, 187 (upper sequence if colors are not important, real number divided by 6), produces sequence A020698. Sequence mentions similar problem, and suggests that upper recursion can be stated in simpler manner:
X_n = 4 * X_(n-1) + A_(n-1)
= 4 * X_(n-1) + A_(n-1) + X_(n-1) - X_(n-1)
= 5 * X_(n-1) + 2 * X_(n-2) + A_(n-2) - 4 * X_(n-2) - A_(n-2)
= 5 * X_(n-1) - 2 * X_(n-2)

2 player team knowing maximum moves

Given a list of N players who are to play a 2 player game. Each of them are either well versed in making a particular move or they are not. Find out the maximum number of moves a 2-player team can know.
And also find out how many teams can know that maximum number of moves?
Example Let we have 4 players and 5 moves with ith player is versed in jth move if a[i][j] is 1 otherwise it is 0.
10101
11100
11010
00101
Here maximum number of moves a 2-player team can know is 5 and their are two teams that can know that maximum number of moves.
Explanation : (1, 3) and (3, 4) know all the 5 moves. So the maximal moves a 2-player team knows is 5, and only 2 teams can acheive this.
My approach : For each pair of players i check if any of the players is versed in ith move or not and for each player maintain the maximum pairs he can make with other players with his local maximum move combination.
vector<int> pairmemo;
for(int i=0;i<n;i++){
int mymax=INT_MIN;
int countpairs=0;
for(int j=i+1;j<n;j++){
int count=0;
for(int k=0;k<m;k++){
if(arr[i][k]==1 || arr[j][k]==1)
{
count++;
}
}
if(mymax<count){
mymax=count;
countpairs=0;
}
if(mymax==count){
countpairs++;
}
}
pairmemo.push_back(countpairs);
maxmemo.push_back(mymax);
}
Overall maximum of all N players is answer and count is corresponding sum of the pairs being calculated.
for(int i=0;i<n;i++){
if(maxi<maxmemo[i])
maxi=maxmemo[i];
}
int countmaxi=0;
for(int i=0;i<n;i++){
if(maxmemo[i]==maxi){
countmaxi+=pairmemo[i];
}
}
cout<<maxi<<"\n";
cout<<countmaxi<<"\n";
Time complexity : O((N^2)*M)
Code :
How can i improve it?
Constraints : N<= 3000 and M<=1000
If you represent each set of moves by a very large integer, the problem boils down to finding pair of players (I, J) which have maximum number of bits set in MovesI OR MovesJ.
So, you can use bit-packing and compress all the information on moves in Long integer array. It would take 16 unsigned long integers to store according to the constraints. So, for each pair of players you OR the corresponding arrays and count number of ones. This would take O(N^2 * 16) which would run pretty fast given the constraints.
Example:
Lets say given matrix is
11010
00011
and you used 4-bit integer for packing it.
It would look like:
1101-0000
0001-1000
that is,
13,0
1,8
After OR the moves array for 2 player team becomes 13,8, now count the bits which are one. You have to optimize the counting of bits also, for that read the accepted answer here, otherwise the factor M would appear in complexity. Just maintain one count variable and one maxNumberOfBitsSet variable as you process the pairs.
What Ill do is:
1. Do logical OR between all the possible pairs - O(N^2) and store it's SUM in a 2D array with the symmetric diagonal ignored. (thats we save half of the calc - see example)
2. find the max value in the 2D Array (can be done while doing task 1) -> O(1)
3. count how many cells in the 2D array equals to the maximum value in task 2 O(N^2)
sum: 2*O(N^2)+ O(1) => O(N^2)
Example (using the data in the question (with letters indexes):
A[10101] B[11100] C[11010] D[00101]
Task 1:
[A|B] = 11101 = SUM(4)
[A|C] = 11111 = SUM(5)
[A|D] = 10101 = SUM(3)
[B|C] = 11110 = SUM(4)
[B|D] = 11101 = SUM(4)
[C|D] = 11111 = SUM(5)
Task 2 (Done while is done 1):
Max = 5
Task 3:
Count = 2
By the way, O(N^2) is the minimum possible since you HAVE to check all the possible pairs.
Since you have to find all solutions, unless you find a way to find a count without actually finding the solutions themselves, you have to actually look at or eliminate all possible solutions. So the worst case will always be O(N^2*M), which I'll call O(n^3) as long as N and M are both big and similar size.
However, you can hope for much better performance on the average case by pruning.
Don't check every case. Find ways to eliminate combinations without checking them.
I would sum and store the total number of moves known to each player, and sort the array rows by that value. That should provide an easy check for exiting the loop early. Sorting at O(n log n) should be basically free in an O(n^3) algorithm.
Use Priyank's basic idea, except with bitsets, since you obviously can't use a fixed integer type with 3000 bits.
You may benefit from making a second array of bitsets for the columns, and use that as a mask for pruning players.

To make an array non-decreasing using dynamic programing

I came accross this question in a programming contest, i think it can be solved by DP but cannot think of any, so plz help. Here's the questn :
There are n stack of coins placed linearly, each labelled from 1 to n. You also have a sack of coins containing infinite coins with you. All the coins in the stacks and the sack are identical. All you have to do is to make the heights of coins non-decreasing.
You select two stacks i and j and place one coin on each of the stacks of coins from stack'i' to stack'j' (inclusive). This complete operations is considered as one move. You have to minimize the number of moves to make the heights non-decreasing.
No. of Test Cases < 50
1 <= n <= 10^5
0 <= hi <= 10^9
Input Specification :
There will be a number of test cases. Read till EOF. First line of each test case will contain a single integer n, second line contains n heights (h[i]) of stacks.
Output Specification :
Output single integer denoting the number of moves for each test case.
for eg: H={3,2,1}
answer is 2
step1: i=2, j=3, H = {3,3,2}
step2: i=3, j=3, H = {3,3,3}