整数划分问题

整数划分问题

将正整数n表示成一系列正整数之和,n=n1+n2+n3+...+nk,其中n>=n2 >= n3  >= ... >= nk >= 1,k >= 1。

正整数n的这种表示称为正整数n的划分。正整数n的不同划分数称为正整数n的划分数。

递归法求解:

分析:正整数n,划分的最大加数为m,划分个数记为q(n,m)

①当n < 1 或  m < 1,划分数为0;

②当最大加数m = 1,只有一种情况, q(n,m) = 1;

③当最大加数m >= n,实际上最大加数m不大于n,q(n,m) = q(n,n) ;

④q(n,n) = q(n,n - 1) + 1;

⑤当n > m > 1时,q(n,m) = q(n,m - 1) + q(n - m,m)

可分为两种情况:(1)划分中包含m的情况,也就是1到n中大于或等于m的数即 n - m,q(n - m,m)(2)划分中不包含m的情况,则划分中所有值都比m小,也就是n的 m - 1 划分:q(n,m - 1)

 1     public static int divide(int n,int m){
 2         if((n < 1) || (m < 1))
 3             return 0;
 4         if((n == 1) || (m == 1))
 5             return 1;
 6         if(n < m)
 7             return divide(n,n);
 8         if(n == m)
 9             return divide(n,m -1) + 1;
10         return divide(n,m - 1) + divide(n - m,m);
11     }

 

 

动态规划法求解:

利用矩阵数组记录数据,数组的最后一个数即为所求。

 1     public static int divideDp(int n, int m){
 2         if (n < 1 || m < 1)
 3             return 0;
 4         int[][] dp = new int[n + 1][m + 1];
 5         dp[0][0] = 0;
 6         for (int i = 1; i <= n; i++){
 7             dp[i][0] = 0;
 8             dp[i][1] = 1;
 9         }
10         for (int j = 1; j <= m; j++){
11             dp[0][j] = 0;
12             dp[1][j] = 1;
13         }
14         
15         for (int i = 1; i <= n; i++){
16             for (int j = 1; j <= m; j++){
17                 if (i < j)
18                     dp[i][j] = dp[i][i];
19                 else if (i == j)
20                     dp[i][j] = dp[i][j - 1] + 1;
21                 else
22                     dp[i][j] = dp[i][j - 1] + dp[i - j][j];
23             }
24         }
25         return dp[n][m];
26     }

 

posted on 2016-11-28 15:13  云兮易  阅读(192)  评论(0)    收藏  举报

导航