P2386 put apples (permutation problem)

content

DP

DFS


Topic description

Put M identical apples on N identical plates, allow some plates to be left empty, and ask how many different distributions there are (5,1,1 and 1,1,5 are the same method)

Input and output format

Input format:

 

The first line is the number of test data t (0 <= t <= 20), each of the following lines includes two integers M and N, separated by spaces. 1<=M, N<=10

 

Output format:

 

For each set of input data M and N, use one line to output the corresponding K.

 

Input and output example

Input Example #1:  Copy

1
7 3

Output Sample #1:  Copy

8

Input Example #2:  Copy

3
3 2
4 3
2 7

Output Sample #2:  Copy

2
4
2

 


This question is similar to the division of numbers. DFS and DP can be used, but it should be noted that the plate of this question is empty.

 

DP

F[ i ][ j ] means that i will be divided into j plates

F[ 0 ][ j ]=F[ 1 ][ i ]=1 There is only one way when the number of apples is 0 or 1

F[ i ][ 1 ]=1 when there is only one plate there is only one way

  • When i<j, that is, when the number of apples is less than the number of plates, F[ i ][ j ]=F[ i ][ i ] because i apples can only occupy i plates at most 
  • 当i>=j时,F[ i ][ j ]=F[ i-j ][ j ] + F[ i ][ j-1 ] 

F[ i ][ j-1 ] means that there are empty disks in j disks, take out the empty disks

F[ ij ][ j ] is the strategy of placing an apple on each plate first


Code:

#include<bits/stdc++.h>
using namespace std;
int f[15][15];//f[i][j]即为i个苹果放在j个盘子里的方案数 
int m,n,ans;
int main()
{
	ios::sync_with_stdio(false);
    int t;
    cin >> t;
    while(t--)
    {
        cin >> m >> n;
        ans=0;
        memset(f,0,sizeof(f));//清空f数组 
        for(int i=1;i<=n;i++)
            f[0][i]=f[1][i]=1;
        for(int i=1;i<=m;i++)
            f[i][1]=1;]
        for(int i=2;i<=m;i++)
            for(int j=2;j<=n;j++)
                if(i<j)//如果苹果比盘子还少 
                    f[i][j]=f[i][i];//等于i个苹果放在i个盘子里 
                else
                    f[i][j]=f[i-j][j]+f[i][j-1];//对于每一次,有两种做法: 
        //1:j个盘子里都放 1个,即 f[i-j][j]
        //2:都不放,即            f[i][j-1]
        cout << f[m][n] << endl;//输出 
    }
    return 0;
}

 


DFS

 

#include<iostream>
using namespace std;
int t,n,k;
int f[11][11];
int sum;

void dfs(int step,int num,int tar)
{
	if(tar==1)
	{
		sum++; return ;
	}
	for(int i=step;i<=num/tar;i++)
		dfs(i,num-i,tar-1);
}

int main()
{
	ios::sync_with_stdio(false);
	cin>>t;
	while(t--)
	{
		cin>>n>>k;
		sum=0;
		dfs(0,n,k);//因为可以有空盘,所以从0开始 
		cout<<sum<<endl;
	}
	return 0;
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326389406&siteId=291194637