Given a matrix AxB with comprising of integers >=0. The sum of each column of the matrix should be non decreasing on moving from left to right. Also the sum of Bth column (last column) is less than or equal to A.
Find the number of distinct matrices of such type for a given A and B.
I tried to solve it using recursion and memoization as follows-
The function solve() is-
ll solve(ll i,ll curlevel)
{
if(dp[i][curlevel]!=-1)
return dp[i][curlevel];
if(i<0)
return dp[i][curlevel]=0;
if(curlevel==B)
return dp[i][curlevel]=test(i,c);
if(curlevel>B)
return dp[i][curlevel]=0;
ll ans=0;
for(ll k=i;k>=0;k--)
{
ans+= test(i,A)* solve(k, curlevel+1);
}
return dp[i][curlevel]=ans;
}
The function test is defined as follows- (It calculates the no of ways a sum ='sum' can occur as a sum of distinct non-negative numbers='places')
ll test(ll sum,ll places)
{
if(mem[sum][places] != -1)
return mem[sum][places];
if(sum==0)
return mem[sum][places]=1;
if(places==0)
return mem[sum][places]=0;
ll val=0;
for(ll i=0;i<=sum;i++)
{
val+=test(sum-i,places-1);
}
return mem[sum][places]=val;
}
This method however is too slow.
Is there a faster way to do this?(Maybe a better combinatorics approach)
You have to precalculate Partitions array - numbers of integer partitions of A into A non-negative parts (including zeros) and taking part order into account (i.e. counting both 0 0 1 and 0 1 0 etc).
Edit:
Partitions(k) = C(A + k - 1, A - 1)
Example for A = 4
Partitions[4] = C(7,3)=7!/(4!3!)=35
whole array:
Partitions = {1,4,10,20,35}
To calculate Partitions, use table - rotated Pascal triangle
for A = 1000 you need about 1000*sizeof(int64) memory (one or two rows) and about 10^6 modulo additions. If you need to make calculations for many A values, just store the whole table (8 MBytes)
Then use this formula: //corrected