整数划分

来源:互联网 发布:mac重新启动快捷键 编辑:程序博客网 时间:2024/05/17 23:16

整数划分

问题描述: 将正整数 n 表示为若干个正整数的和, 问共有多少种表示? (不考虑排列问题)

上述描述是整数划分中最基本的描述, 整数划分是一类问题的总称. 正整数及其个数的不同约束可以得到不同的整数划分问题.

1. 最大值为 k 的正整数

该问题是最基本的约束条件, 对该约束分析如下:

f(n,k) 为问题的解 ( 即将正整数 n 划分为不大于 k(k1) 的正整数和的划分个数 ) , 则有下述等式成立

f(n,k)=0,1,f(n,n),f(n,k1)+f(nk,k),n<0;n=0;n>0k>n;n>0kn.

根据上述结果, 得到如下 C++ 程序

int dp(int n, int k) {    /*        求 n 的最大值为 k 的划分的个数        f(n, k) = f(n, k - 1) + f(n - k, k)        由上式可得: dp[n] += dp[n - k], (n >= k 且 dp[0] = 1)    */    if (n <= 0 || k <= 0)        return 0;    int dp[128] = { 1 };    int realK = k <= n ? k : n;    int iN, jK;    for (jK = 1; jK <= realK; ++jK)        for (iN = jK; iN <= n; ++iN)            dp[iN] += dp[iN - jK];    return dp[n];}

2. 若干个奇正整数

该问题可以转化为问题 5 进行解决.

3. 若干个不同的正整数

该问题是最基本的约束条件, 对该约束分析如下:

f(n,k) 为问题的解 ( 即将正整数 n 划分为不大于 k(k1) 的正整数和的划分个数 ) , 则有下述等式成立

f(n,k)=0,1,f(n,n),f(n,k1)+f(nk,k1),n0k0;n=1k>0;n>1k>n;n>1kn.

根据上述结果, 得到如下 C++ 程序

int dpOfDifNum(int n, int k) {    /*        求 n 的最大值为 k 的划分的个数        f(n, k) = f(n, k - 1) + f(n - k, k - 1)        由上式可得: dp[n] += dp[n - k], (n >= k 且 dp[0] = 1)    */    if (n <= 0 || k <= 0)        return 0;    int dp[128] = { 1 };    int realK = k <= n ? k : n;    int iN, jK;    for (jK = 1; jK <= realK; ++jK)        for (iN = n; iN >= jK; --iN)            dp[iN] += dp[iN - jK];    return dp[n];}

4. 若干个给定的正整数

该问题根据最基本的问题推导:

设给定的 m 个正整数为 k1,k2,...,km ,记个数为 f(n) , 则有一下等式成立

f(n,ki)=0,1,f(n,n),f(n,ki1)+f(nki,ki),n<0;n=0;n>0ki>n;n>0kin.

根据上述结果, 得到如下 C++ 程序

int dpMArr(vector<int>& mArr, int n){    /*         mArr 给定的正整数        n 需要求的数    */    if (mArr.size() <= 0 || n <= 0)        return 0;    int dp[10240] = { 1 };    int m = mArr.size(),        realM = m <= n ? m : n;    int iN, jM;    for (jM = 0; jM < realM; ++jM)        for (iN = mArr[jM]; iN <= n; ++iN)            dp[iN] += dp[iN - mArr[jM]];    return dp[n];}

5. m 个正整数之和

该问题是最基本的约束条件, 对该约束分析如下:

给问题等价于 (nm) 的最大值为 m 的划分的个数。

f(n,k) 为问题 1 的解 ( 即将正整数 n 划分为不大于 k(k1) 的正整数和的划分个数 ) , 则该问题的解为 f(nm,m)

根据上述分析, 得到如下 C++ 程序

int mSumOfNum(int n, int m){    return dp(n - m, m);}
原创粉丝点击