There are n non-differentiated items, dividing them into m-groups, and finding the remainder of the partitioning method number-modulus m.
Restrictions:
1≤m≤n≤1000
2≤m≤10000
Input
n = 4
m = 3
M = 10000
Output
4 (1+1+2=1+3=2+2=4)
Reproduced the knowledge point of explanation
Such a division is called the M division of N, which can be defined as a DP array:
DP[I][J] = The total number of I divisions of J.
The difficulty of a recursive relationship is not repetition. We use a standard to turn problems into sub-problems, a standard that requires a new definition. We define the M partition of n specifically for a set {Ai},{ai} to satisfy ∑mi=1ai = N. You can see that {AI} has a total m number, which is not necessarily greater than 0.
This is the standard: whether there is a ai=0, which can be divided into two types of {AI}:
1, there is no one ai=0
At this point {ai} is equal to the number of {ai–1}, which is the M partition of N–m. It is not difficult to understand, each number in the collection minus 1, altogether minus M.
At this time dp[i][j] = Dp[i][j–i].
2. There is a ai=0
The number of {AI} at this time equals the m–1 division of N. Can think this way, there is ai=0, the partition must be less than M group, then at least one group can meet the same number of divisions.
At this time dp[i][j] = dp[i–1][j].
Then the total number of {AI} partitions is the combination of these two cases, dp[i][j] = Dp[i][j–i] + dp[i–1][j].
#include <stdio.h>
const int MAXN = 1000+10;
int n, M, m;
int DP[MAXN][MAXN];
void Solve ()
{
int i,j;
Dp[0][0] = 1;
for (i = 1; I <= m; i++)
{for
(j = 0; J <= N; j + +)
{
if (j-i >= 0)
{
Dp[i][j] = (DP [I-1] [j] + dp[i][j-i])% M;
}
else
{
Dp[i][j] = Dp[i-1][j];}}
}
printf ("%d\n", Dp[m][n]);
}
int main ()
{while
(scanf ("%d%d%d", &m, &n, &m)! = EOF
) {
solve ();
}
return 0;
}