[Question solution] Division of numbers

Title source: loj

Title description

The integer n is divided into k parts, and each part cannot be empty. Any two schemes are not the same (regardless of order).
For example: n=7, k=3, the following three divisions are considered the same.

1,1,5;
1,5,1;
5,1,1.

Ask how many different divisions are there.

Input format

n,k (6<n≤200,2≤k≤6)

Output format

1 integer, that is, different divisions.

Sample input and output

enter

7 3

Output

4

Instructions/tips

The four classification methods are:
1,1,5;
1,2,4;
1,3,3;
2,2,3.

Ideas

This question is to find the number of schemes that divide the number n into k parts. That is to find the number of solutions of the equation x1+x2+…+xk=n,1<=x1<=x2<=…<=xk.
The search method is to enumerate the values ​​of x1, x2...xk in turn, and then judge. If you search directly like this, the running speed of the program is very slow. But because the data scale of this question is relatively small, if the "upper bound" and "lower bound" of the expansion node are controlled well, the solution can be quickly obtained.
Restrictions:

  1. Since the decomposition number does not consider the order, we set the decomposition number to increase sequentially, so the lower bound of the expansion node should be no less than the value of the previous expansion node, that is, a[i-1]<=a[i]
  2. Suppose we have decomposed n into a[1]+a[2]+…+a[i-1], then the maximum value of a[i] is divided into k-i+1 parts i~k equally, That is, if m=n-(a[1]+a[2]+…+a[i-1]), then a[i]<=m/(k-i+1), so the " The upper bound is m/(k-i+1)

code

#include<bits/stdc++.h>
using namespace std;
int n,m,a[10],anss;
void dfs(int k)
{
    
    
	if (n==0) return; //如果已经没有数值可以分了,说明之前的分法是不合理的,直接返回 
	if (k==m) //已经分到最后一份 
	{
    
    
		if (n>=a[k-1]) anss++; //对最后一份直接进行判断,如果最后一份的值大于等于上一份的值,说明当前的分法是合理的,直接anss++ 
		return ;
	}
	for (int i=a[k-1];i<=n/(m-k+1);i++)
	{
    
    
		a[k]=i;
		n-=i; //n分出去一个i这么大的数,要减
		dfs(k+1); //分下一个数 
		n+=i; //不要忘记加回来 
	}
}
int main()
{
    
    
	scanf("%d%d",&n,&m);
	a[0]=1; //初始条件,保证接下来“i=a[k-1]”时第一个i是1 
	dfs(1);
	cout<<anss<<endl;
	return 0; 
}

Guess you like

Origin blog.csdn.net/weixin_45485187/article/details/103199211