整数划分

来源:互联网 发布:图文排版软件 编辑:程序博客网 时间:2024/05/22 10:40
将正整数n表示成一系列正整数之和:n=n1+n2+…+nk, 
其中n1≥n2≥…≥nk≥1,k≥1。 
正整数n的这种表示称为正整数n的划分。求正整数n的不 
同划分个数。 
例如正整数6有如下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。


整数划分是利用递归和动态规划的经典算法。解决此类的问题的关键在于找到状态转移方程。在本题中设待划分整数位n,划分后子项中最大数不超过m(即<=m)。

1:如果n=4,当m为1时即表示划分后的式子中最大为1,那么每一项只能为1(即只有一种结果),故f(4,1)=1。

2:当n为1时,不论m为何,只有一种划分结果{1},故f(1,m)=1。

3:当n=m时,f(n,n)即表示整数n的划分结果,这里有两种可能,一是划分后子项最大就是n,这样显然只有一种结果。另一种是划分后子项最大小于n,那我们可以将其表示成f(n,n-1)。

4:最后就是考虑n>m的情况。也和第三种情况一样分为两种可能。第一种情况下,n划分后的式子中必然会有一个m(即其中一位已经固定),那么我们只需要再划分去掉m之后的整数f(n-m,m)。第二种情况下,最大子项小于m,那么必然小于等于m-1,故我们可以表示成f(n,m-1)。

简单的描述即为:

                             f(n, m)=   1;                (n=1 or m=1)
                             1+ f(n, m-1);                (n=m)
                             f(n-m,m)+f(n,m-1);      (n>m)

                             f(n, n);                        (n<m)

代码如下

import java.util.Scanner;public class Main {/** * 整数划分 * @param args */public static void main(String[] args) {// TODO Auto-generated method stubScanner in=new Scanner(System.in);int m=in.nextInt();while((m--)!=0){int n=in.nextInt();System.out.println(run(n,n));}}public static int run(int n,int m){if(n==1||m==1) return 1;if(n==m) return 1+run(n,m-1);if(n<m) return run(n,n);//if(n>m) return run(n-m,m)+run(n,m-1);}}

此算法的一个变形问题是苹果摆放问题,有m个苹果放到n个盘子(盘子可以为空且5个苹果3个篮子时113和311是同一种放法)。此题的思路和整数划分是一致的,只是第二个参数有点变化(本题的第二个参数n表示整数划分后的子项数量)。按情况可以划分为以下四种情况:

(1):m=1或n=1时必然只有一种放法。

(2):m<n时不管怎么放必然至少有n-m个盘子是空的,因此run(m,n)可以转化为run(m,m)。

(3):m>n时有两种处理方式,一是给每个盘子先放一个苹果再将m-n个苹果随机分配(run(m-n,n))。另一个情况是空掉一个盘子,对剩下的n-1个盘子进行分配(run(m,n-1))。

(4):m==n时处理方式和(3)是一样的,只是情况1下结果为1.故可以直接理解为1+run(m,n-1)。

代码如下:

public static void main(String[] args) {// TODO Auto-generated method stubScanner in=new Scanner(System.in);int m=in.nextInt();int n=in.nextInt();System.out.println(run(m,n));}public static int run(int m,int n){if(m==1||n==1) return 1;if(m<n){return run(m,m);}else{if(m>n){return run(m-n,n)+run(m,n-1);}else{return 1+run(m,n-1);}}}



0 0
原创粉丝点击