poj1664 put an apple
Time Limit: 1000MS |
|
Memory Limit: 10000K |
Total Submissions: 33661 |
|
Accepted: 20824 |
Description
Put m the same apples on n the same plate, allow some plates to be empty, ask how many different ways? (denoted by k) 5,1,1 and 1,5,1 are the same kind of sub-method.
Input
The first line is the number of test data t (0 <= T <= 20). Each of the following lines contains two integers m and n, separated by a space. 1<=m,n<=10.
Output
For each set of data entered M and N, the corresponding k is output in one line.
Sample Input
17 3
Sample Output
8
The key is to find the recurrence of the relationship, to achieve not heavy and not dew!
The recursive relationship is that for putting n apples on M plates, because you can have empty plates,
So there are two situations: one: No empty plates appear, two: empty plates appear
For one obviously each plate contains at least one apple, so at this time dp[n][m]=dp[n-m][m];
For two, dp[n][m]=dp[n][m-1];
Finally note the initialization of the DP array
The reason for the second consideration of all the situation:
Assuming that 5 fruit is placed in 3 plates, the j==2 has been considered a tray is empty, so j==3 when considering an empty plate case also contains two is empty situation
#include <bits/stdc++.h>
using namespace Std;
int main ()
{
int n,m,i,j,k,dp[105][105];
int T;memset (Dp,0,sizeof (DP));
for (i=0;i<=100;++i) dp[0][i]=1;
for (I=1;i<=100;++i)
for (J=1;J<=100;++J)
DP[I][J]=DP[I][J-1]+DP[I-J][J];
cin>>t;
while (t--) {
cin>>n>>m;
cout<<dp[n][m]<<endl;
}
return 0;
}
Recursive posture:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace Std;
int solve (int n,int m)
{
if (n = = 1 | | m = = 1 | | n = = 0)
return 1;
if (n<m)
return solve (n,n);
Else
return solve (n,m-1) +solve (n-m,m);
}
int main ()
{
int t,n,m;
scanf ("%d", &t);
while (t--)
{
scanf ("%d%d", &n,&m);
printf ("%d\n", Solve (n,m));
}
return 0;
}
This topic leads to a similar problem, integer division, to find an integer can be divided into how many different integers and
For example:
Integers such as n==6 are divided into (requires that all numbers are less than n)
6
5 + 1
4 + 2, 4 + 1 + 1
3 + 3, 3 + 2 + 1, 3 + 1 + 1 + 1
2 + 2 + 2, 2 + 2 + 1 + 1, 2 + 1 + 1 + 1 + 1
1 + 1 + 1 + 1 + 1 + 1
A total of 11 kinds.
Think about it like an apple, just put n fruit in n plates!
#include <bits/stdc++.h>
using namespace Std;
int solve (int n,int m)
{
if (n==0| | m==1| | N==1) return 1;
if (n>=m)
return solve (n-m,m) +solve (n,m-1);
else return solve (n,m-1);
}
int main ()
{
int n,m;
while (cin>>n) cout<<solve (n,n) <<endl;
return 0;
}
Dividing a positive integer into a continuous sum of positive integers
such as 15 can be divided into 4 consecutive integers in the form of addition:
15
7 8
4 5 6
1 2 3) 4 5
First consider the general form, set N as the divided positive integer, x is the smallest integer after division, if N has a division, then
The result is x, if there are two divisions, X and x x + 1, if there is a M division, that is x, x x + 1, x x + 1 x + 2 、... 、 x x + 1 x + 2 ... x + m-1
Add each result to a formula (I * x + i * (i-1)/2) = N,i is the number of positive integers added after the current division.
The partition that satisfies the condition is all the cases in which x is a positive integer.
As in the example above, when i = 1 o'clock, which is divided into a positive integer, x = 15, when i = 2 o'clock, x = 7.
When x = 3 o'clock, x = 4, when x = 4 o'clock, 4/9, is not a positive integer, therefore 15 cannot be divided into 4 positive integers to add.
When x = 5 o'clock, x = 1.
Here's another question, what is the maximum value of this I? But one thing is certain, it must be smaller than N. We can make a hypothesis,
Suppose that n can be split into a minimum of 1, as in the previous Example 1 2 3 4 5. This is the division of the maximum number of N. If this hypothesis is not met,
Then I must be smaller than the number of positive integers in this division. So you can get such a formula I * (i + 1)/2 <= n, i.e. when I meet
This formula is only possible when n is divided.
To synthesize the above, the source program is as follows
int split1 (int n)
{
int I, j, m = 0, x, T1, T2;
Here i + 1 becomes i-1, because I * (i-1)/2 This equation is used many times below,
To avoid duplication of calculations, this value is calculated and saved in T1. and changed the <= number to the < number.
for (i = 1; (T1 = i * (i-1)/2) < n; i++)
{
T2 = (N-T1);
x = t2/i;
if (x <= 0) break;
if ((n-t1)% i = = 0)
{
printf ("%d", x);
for (j = 1; j < I; J + +)
printf ("%d", X + j);
printf ("\ n");
m++;
}
}
return m;
}
poj1664 Apple (DPORDFS) && series breakout (integer division)