1.NOI 8787: Division of Numbers (dividing n into k numbers )
-
Total time limit:
-
1000ms
-
Memory Limit:
-
65536kB
-
Describe
-
The integer n is divided into k parts, and each copy cannot be empty, and any two parts cannot be the same (regardless of order).
For example: N=7,k=3, the following three kinds of sub-methods are considered to be the same.
1,1,5; 1,5,1; 5,1,1;
Ask how many different sub-methods there are. Output: An integer, which is a different method of division.
-
Input
-
Two integers n,k (6 < n <= 200,2 <= k <= 6), separated by a single space in the middle.
-
Output
-
An integer, that is, a different method of division.
-
Sample input
-
3 ·
-
Sample output
-
4
-
Tips
-
The four kinds of methods are: 1,1,5;1,2,4;1,3,3;2,2,3.
-
Source
-
The second problem of the NOIP2001 in the improvement group
#include <iostream>using namespacestd; #include<cstdio>Long Long intf[201][Ten];intn,k;intMain () {scanf ("%d%d",&n,&k); for(intI=1; i<=n;++i) for(intj=1; j<=i&&j<=k;++j) {if(j==1) F[i][j]=1; Elsef[i][j]=f[i-1][j-1]+f[i-J] [j]; } cout<<f[n][k]<<Endl; return 0; }
View Code
2. NOI7215: A simple integer partitioning problem (dividing n into several numbers )
-
Total time limit:
-
100ms
-
Memory Limit:
-
65536kB
-
Describe
-
The positive integer n is represented as a series of positive integers of sum, n=n1+n2+...+nk, wherein N1>=n2>=...>=nk>=1, k>=1.
This representation of a positive integer n is called a division of positive integer n. The number of different divisions of positive integer n is called the number of divisions of positive integer n.
-
Input
-
The standard input contains several sets of test data. Each set of test data is an integer N (0 < n <= 50).
-
Output
-
For each set of test data, the number of divisions of the output N.
-
Sample input
-
5
-
Sample output
-
7
-
Tips
-
5, 4+1, 3+2, 3+1+1, 2+2+1, 2+1+1+1, 1+1+1+1+1
#include <iostream>using namespacestd; #include<cstdio>#defineN 51#include<cstring>intF[n][n];/*F[n][n] Description The number of divisions dividing N into 1--n parts*/intMain () {intN; while(cin>>n)/*Note that while in C + +, there is no error, but the runtime does not loop*/{memset (F,0,sizeof(f)); for(intk=1; k<=n;++k) for(intI=1; i<=n;++i)/*dp Equation Description*/ { if(k==1|| i==1) F[i][k]=1;/*Divide any number into 1 points, or divide 1 into K-parts, all 1 .*/ if(i==k) F[i][k]=f[i][k-1]+1;/*when I==k, (a). In the case of N in the division, only one is {n}, (b). The Division does not contain n, when the largest number in the division must be smaller than n, that is, all (n-1) division of N. */ if(i<k) F[i][k]=f[i][i];/*when i<k, I can only be divided into I parts, so it is f[i][i].*/ if(i>k) F[i][k]=f[i-k][k]+f[i][k-1];/*when i>k, I was divided into K parts include: The maximum number of k, that is, the remaining number of i-k (which may also contain k), so is f[i-k][k], two: does not contain K, that is f[i][k-1]*/} printf ("%d\n", F[n][n]); } return 0;}
Code:
3. A comparison of the number of divisions and the number of non-divisions
1. No number of divisionsif(k==1|| i==1) F[i][k]=1;/*Divide any number into 1 points, or divide 1 into K-parts, all 1 .*/ if(i==k) F[i][k]=f[i][k-1]+1;/*when I==k, (a). In the case of N in the division, only one is {n}, (b). The Division does not contain n, when the largest number in the division must be smaller than n, that is, all (n-1) division of N. */ if(i<k) F[i][k]=f[i][i];/*when i<k, I can only be divided into I parts, so it is f[i][i].*/ if(i>k) F[i][k]=f[i-k][k]+f[i][k-1];/*when i>k, I was divided into K parts include: The maximum number of k, that is, the remaining number of i-k (which may also contain k), so is f[i-k][k], two: does not contain K, that is f[i][k-1]*/2. There are number of divisionsif(j==1) F[i][j]=1;Elsef[i][j]=f[i-1][j-1]+f[i-J] [j]; There is no limit to the number of divisions, the main treatment of K>i,i==The case of K, and the f[i][k] represents no longer dividing K-times but dividing 1--k Times
4. Divide n into divisions that are not less than M:
1). If you divide multiple integers, the same can exist:
#include <iostream>using namespacestd; #include<cstdio>#defineN 51intF[n][n];/*f[i][j] Meaning: Divide the number of I in the case of no more than J*/intMain () {intn,m; scanf ("%d%d",&n,&m); for(intI=0; i<=n;++i) {f[0][i]=0; f[i][0]=0; } for(intI=1; i<=n;++i) for(intj=1; j<=m;++j) {if(i==j) F[i][j]=f[i][j-1]+1;/*i==j: 1. Divide I into more than j-1, 2. Think of I as a copy, J, so f[0][1--m] should be 1, that is, to deal with a situation*/ Else if(i>j) F[i][j]=f[i][j-1]+f[i-J] [j]; ElseF[i][j]=f[i][i];/*when j>i for f[i][...] The Division has no effect, so does not count*/} printf ("%d\n", F[n][m]); return 0;}
View Code
2). If you divide a number of different integers:
#include <iostream>using namespacestd; #include<cstdio>#defineN 51intF[n][n];/*f[i][j] Meaning: Divide the number of I in the case of no more than J*/intMain () {intn,m; scanf ("%d%d",&n,&m); for(intI=0; i<=n;++i) {f[0][i]=0; f[i][0]=0; } for(intI=1; i<=n;++i) for(intj=1; j<=m;++j) {if(i==j) F[i][j]=f[i][j-1]+1;/*i==j: 1. Divide I into more than j-1, 2. Think of I as a copy, J, so f[0][1--m] should be 1, that is, to deal with a situation*/ Else if(i>j) F[i][j]=f[i][j-1]+f[i-j][j-1]; ElseF[i][j]=f[i][i];/*when j>i for f[i][...] The Division has no effect, so does not count*/} printf ("%d\n", F[n][m]); return 0;}
View Code
3). Summary:
. The practice of dividing n into divisions less than M:
1. initialization, f[i][0]=f[0][j]=0;
2. Transfer equation if i==j, f[i][j]=f[i][j-1]+1
If I>j F[i][j]=f[i][j-1]+f[i-j][j] (repeatable) IF i>j f[i][j]=f[i][j-1]+f[i-j][j-1] (non-repeatable)
If I<f f[i][j]=f[i][i];
The problem of integer classification type--special practice