整数划分有两种
1.不限定划分的个数
如:
5 = 1+1+1+1+1.
5 = 1+1+1+2.
5 = 1+2+2.
5 = 1+1+3.
5 = 2+3.
5 = 1+4.
5 = 5.
可以利用组合数学中的母函数:G(x) = (1+x^1+x^2+x^3+...+x^n)(1+x^2+x^4+x^6+...+x^(2*p))(1+x^3+x^6+...+x^(3*q))+...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace 整数划分
{
class Program
{
static void Main(string[] args)
{
int N;
int[] c1 = new int[11]; // 存储结果
int[] c2 = new int[11]; // 辅助数组
string[] input = Console.In.ReadToEnd().Split(new char[] {' ','\t','\n','\r'}, StringSplitOptions.RemoveEmptyEntries);
N = int.Parse(input[0]);
// 初始数组,因为任何数总有一种拆分,故c1[i]=1
for (int i = 0; i <= N; i++)
{
c1[i] = 1;
c2[i] = 0;
}
for (int i = 2; i <= N; i++)
{
// 每次循环加入若干个i时的次数
for (int j = 0; j <= N; j++)
for (int k = 0; k + j <= N; k += i)
c2[k + j] += c1[j];
// 再次初始数组
for (int j = 0; j <= N; j++)
{
c1[j] = c2[j];
c2[j] = 0;
}
}
Console.WriteLine("{0}的整数划分为{1}",N,c1[N]);
}
}
}
不过,这个题目也可以用多重背包。
c2[0] = 1; for (int i = 1; i <= N; i++) for (int j = i; j <= N; j++) { c2[j] += c2[j-i]; } Console.WriteLine("{0}的整数划分为{1}", N, c2[N]);
2.另外一种整数划分是限制划分的数目
这种情况用限制多重背包可解
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int f[111][111];
int main(int argc, char **argv) {
int T;
int m, n;
int i, j, k;
cin >> T;
while (T--) {
cin >> m >> n;
// memset(f, -1, sizeof(f));
for (i = 0; i <= n; ++i)
for (j = 0; j <= m; ++j)
f[i][j] = -1;
f[0][0] = 1;
for (j = 1; j <= m; ++j) {
for (i = 1; i <= n; ++i) {
for (k = j; k <= m; k++) {
if (f[i - 1][k - j] != -1) {
if (f[i][k] == -1)
f[i][k] = f[i - 1][k - j];
else
f[i][k] += f[i - 1][k - j];
}
}
}
}
// for (i = 1; i <= n; ++i) {
// for (j = 1; j <= m; ++j)
// cout << f[i][j] << ' ';
// cout << endl;
// }
cout << f[n][m] << endl;
}
return 0;
}