整数划分有两种

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;
}

posted on 2011-09-10 14:30  Mathida  阅读(179)  评论(0编辑  收藏  举报