0002算法--------整数划分问题算法分析及JAVA代码完美实现

来源:互联网 发布:linux mint 内核版本 编辑:程序博客网 时间:2024/05/18 03:15
整数划分算法分析以及JAVA代码完美实现
一、问题描述
整数划分:将正整数n表示成一系列正整数只和,n = n1 + n2 + …… + nk,其中n1 >= n2 >= nk >= 1,k >= 1 。正整数 n 的这种表示称为正整数 n 的划分,正整数 n 的所有不同的划分个数总和称为正整数 n 的划分数,记作p(n)。
例如:
正整数 3 有如下3种不同的划分,即p(n)= 3。
3;
2 + 1;
1 + 1 + 1;
正整数 6 有如下11种不同的划分,即p(n)= 11。
6;
5 + 1;
4 + 2,4 + 1 + 1;
3 + 3,3 + 2 + 1,3 + 1 + 1 + 1;
2 + 2 + 2,2 + 2 + 1 + 1,2 + 1 + 1 + 1 + 1;
1 + 1 + 1 + 1 + 1 + 1;
二、整数划分算法分析
1、从简单问题开始入手,对于给定正整数3来说,它可以划分为:
  • 3;
  • 2 + 1;
  • 1 + 1 + 1;
其划分的的思想为:
1)将正整数3划分为其本身,即 3 = 3;
2)将正整数3分割成为仅小于 3 的正整数 2,即3 - 1 = 2,和剩下部分 1,即3 - 2 = 1,所以可以将 3 划分为 3 = 2 + 1;
3)将第二步分割后中等于1的正整数不再进行划分,对大于 1 的正整数 2 继续分割,分割为仅小于 2 的正整数 1,即 2 -1 = 1,和剩下部分 1,即 2 - 1 = 1 ,所以可以将 3 继续划分为 3 = 1 + 1 + 1;
2、提升问题规模,对于给定正整数5,它可以划分为:
  • 6;
  • 5 + 1;
  • 4 + 2,4 + 1 + 1;
  • 3 + 3,3 + 2 + 1,3 + 1 + 1 + 1;
  • 2 + 2 + 2,2 + 2 + 1 + 1,2 + 1 + 1 + 1 + 1;
  • 1 + 1 + 1 + 1 + 1 + 1;
1)将正整数6划分为其本身,即 6
2)将正整数6划分为仅小于 6 的正整数 5 即 6 - 1 = 5,和剩下部分 1 即 6 - 5 = 1,所以可以将6划分为6 = 5 + 1
3)将第二步分割后中等于1的正整数不再进行划分,对大于 1 的正整数 5继续分割,分割为仅小于 5 的正整数 4,和剩下部分 2 ,即6 = 4 + 2
4)将第三步分割后中大于一的最小正整数 2 进行分割,可分割为 2 = 1 + 1,所以可以将6 = 4 + 1 + 1;(注意:每一步仅对大于 1 的最小正整数进行划分)
5)将正整数6划分为仅小于 4 的正整数 3 即 6 - 3= 3,和剩下部分 3 即 6 - 3 = 3,所以可以将6划分为6 = 3 + 3
6)将第五步分割后中大于一的最小正整数 3 进行分割,可分割为仅小于3的正整数 2 和剩下部分 1。即 3 = 2 + 1,所以可以将6划分为6 = 3 + 2 + 1,对等式右边的2 又可以划分为仅小于2的正整数1,和剩下部分1,所以可以将6划分为6 = 3 + 1 + 1 + 1
7)将正整数6划分为仅小于 3 的正整数 2 即 4 - 1= 1,和剩下部分 2 以及 另一部分 2 。即可以将6划分为6 = 2 + 2 + 2
8)将第七步分割后中大于一的最小正整数 2 进行分割,由于第七步划分后的等式有 3 个 2,所以一次将 3 个 2 划分为 1 + 1,故可以将6划分为:6 = 2 + 2 + 1 + 16 = 2 + 1 + 1 + 1 + 1
9)将第八步分割后中大于一的最小正整数 2 进行分割,分割后为2 = 1 + 1,所以可以将6划分为:6 = 1 + 1 + 1 + 1 + 1 + 1
三、归纳总结
在正整数 n 的所有不同的划分中,将最大加数 n1 不大于 m 的划分个数记作q(n,m)。可以建立q(n,m)的如下递归关系。
1)q(n,1) = 1,n > = 1 。
当最大加数 n1 不大于 1 时,任何正整数 n 只有一种划分形式,即 n = 1 + 1 + … + 1(共 n 个1)。
2)q(n,m)= q(n,n),m >= n;
最大加数 n1 实际上不能大于 n 。因此,q(1,m) = 1;
3)q(n,n)= 1 + q(n,n - 1)。
正整数 n 的划分由 n1 = n 的划分和 n1 <= n - 1的划分组成 。
4)q(n,m)= q(n,m - 1)+q(n - m,m - 1),n > m > 1。
正整数 n 的最大加数 n1 不大于 m 的划分有 n1 = m 的划分和n1 <= m - 1的划分组成。
四、JAVA代码实现
public class IntegerDivide {public static void main(String[] args) {// TODO Auto-generated method stub//分别用正整数3和正整数6进行用例测试int num1 = 3;int num2 = 6;System.out.println("整数3的划分数为 : " + dividePrintln(3));System.out.println("整数6的划分数为 : " + dividePrintln(6));}public static int integerDivide(int n, int m){// n 和 m 为非正整数  返回0if(n < 1 || m < 1) {return 0;} else if(m == 1 || n == 1){        //对应情况为:q(n,1) = 1,n > = 1,q(1,m) = 1return 1;} else if(m > n){        //对应情况为:q(n,m)= q(n,n),m  >=  n;return integerDivide(n, n);} else if(n == m){    //对应情况为:q(n,n)= 1 + q(n,n - 1)return 1 + integerDivide(n, n - 1);} else {  //对应情况为:q(n,m)= q(n,m - 1)+q(n - m,m - 1)return integerDivide(n, m - 1) + integerDivide(n - m, m);}}        //中间函数,对给定需要进行划分的正整数调用integerDivide函数。public static int dividePrintln(int num){return integerDivide(num,num);}}


0 0
原创粉丝点击