Divide integers (recursively) and output the result of the division

Divide integers (recursively) and output the result of the division

Explain the problem, what is integer division?

  • n=m1+m2+...+mi; (where mi is a positive integer and 1 <= mi <= n), then {m1,m2,...,mi} is a division of n.
  • If the maximum value in {m1,m2,...,mi} does not exceed m, that is, max(m1,m2,...,mi)<=m, it is said to belong to an m partition of n. Here we record the number of m divisions of n as f(n,m);
  • For example, when n=5, we can obtain the following divisions (note that m>=5 in the example)

5 = 5 
   = 4 + 1 
   = 3 + 2 
   = 3 + 1 + 1 
   = 2 + 2 + 1 
   = 2 + 1 + 1 + 1 
   = 1 + 1 + 1 + 1 + 1

According to the relationship between n and m, consider the following situations:

   (1) When n=1, no matter what the value of m is (m>0), there is only one division, namely {1};

   (2) When m=1, no matter what the value of n is, there is only one division, that is, n 1s, {1,1,1,...,1};

   (3) When n=m, according to whether n is included in the division, it can be divided into two cases:

      (a) In the case where n is included in the division, there is only one, namely {n};

      (b) In the case where n is not included in the division, the largest number in the division must also be smaller than n, that is, all (n-1) divisions of n. So q(n,n) =1 + q(n,n-1);

   (4) When n<m, since it is impossible to have negative numbers in the division, it is equivalent to q(n,n);

   (5) But when n>m, according to whether the maximum value m is included in the division, it can be divided into two cases:

       (a) The case where m is included in the division, ie {m, {x1,x2,...xi}}, where the sum of {x1,x2,...xi} is nm, so in this case it is q(nm ,m)

       (b) In the case where m is not included in the division, all the values ​​in the division are smaller than m, that is, the (m-1) division of n, the number of which is q(n, m-1);

      So q(n, m) = q(nm, m)+q(n,m-1);

      In summary:

                             q(n, m) =   1;                  (n=1 or m=1)

                             q(n,m) =  q(n, n);           (n<m)

                             1+ q(n, m-1);                  (n=m)

                             q(n-m,m)+q(n,m-1);      (n>m)

Recursive algorithm:

code show as below:

#include<iostream>
using namespace std;
int q(int n, int m) {
	if(n < 1 || m < 1) return 0;
	if(n == 1 || m == 1) return 1;
	if(n < m) return (n, n);
	if(n == m) return q(n, m-1) + 1;
	return q(n, m-1) + q(n-m, m);
}
int main() {
	cout<<q(6, 6)<<endl;
	return 0;
}

Dynamic programming:

#include <iostream>
#define  MYDATA long long
const MYDATA MOD = 1000000007;
#define MAXNUM 1005 //Maximum times  
long ww[MAXNUM * 11][MAXNUM * 11];
long dp(int n, int max);
using namespace std;
int main() {
	int n;
	int m;
	long count;
	while (1) {
		cin >> n;
		cout << dp(n, n) << endl;
	}
	return 0;
}
long dp(int n, int max) {
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= i; j++) {
			if (j == 1 || i == 1) {
				ww[i][j] = 1;
			} else {
				if (j == i)
					ww[i][j] = (ww[i][j - 1] + 1) % MOD;
				else if ((i - j) < j)
					ww[i][j] = (ww[i - j][i - j] + ww[i][j - 1]) % MOD;
				else
					ww[i][j] = (ww[i - j][j] + ww[i][j - 1]) % MOD;
			}
		}
	return ww[n][max];
}

Output result:

#include <stdio.h>
int mark[256];
int n;
void DFS(int sum, int k, int prio) {
	if(sum > n) {
		return;
	} else if(sum == n) {
		int i;
		printf("=");
		for( i = 0; i < k-1; i++) {
			printf("%d+",mark[i]);
		}
		printf("%d\n",mark[i]);
	} else {
		for(int j = prio; j > 0; j--) {
			mark[k] = j;
			sum += j;
			DFS(sum,k+1,j);
			sum -= j; // restore the scene
		}
	}
}
int main() {
	scanf("%d", &n);
	DFS(0, 0, n);
	return 0;
}

Guess you like

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