基本算法(整数划分)

来源:互联网 发布:王思聪 知乎 编辑:程序博客网 时间:2024/06/11 09:03
所谓整数划分,是指把一个正整数n写成为
其中,
为正整数,并且
为n的一个划分。
如果
中的最大值不超过m,即
,则称它属于n的一个m划分。

这里我们记n的m划分的个数为
例如,当n=4时,有5个划分,即
注意:
被认为是同一个划分。
根据n和m的关系,考虑一下几种情况:
(一)当
时,无论m的值为多少
,只有一种划分,即
(二)当
时,无论n的值为多少,只有一种划分,即n个1,
(三)当
时,根据划分中是否包含n,可以分为以下两种情况:
(1)划分中包含n的情况,只有一个,即
(2)划分中不包含n的情况,这时划分中最大的数字也一定比n小,即n的所有
划分。
因此
(四)当
时,由于划分中不可能出现负数,因此就相当于
(五)当
时,根据划分中是否包含最大值m,可以分为以下两种情况:
(1)划分中包含m的情况,即
,其中
的和为n-m,因此这种情况下为
(2)划分中不包含m的情况,则划分中所有值都比m小,即n的
划分,个数为
因此
 
综上所诉:    

20 以内的一个数:
#include <stdio.h>

int main()

{
 int s, i, j, k, t, u;

 static int a[21][800][21];

 printf("input s(s<=20):"); scanf_s("%d", &s);

 a[2][1][1] = 1; a[2][1][2] = 1; a[2][2][1] = 2;

 u = 2;

 for (k = 3; k <= s; k++)

 {
  for (j = 1; j <= u; j++)

  {
   a[k][j][1] = 1;

   for (t = 2; t <= k; t++)         // 实施在k−1所有划分式前加1操作 

    a[k][j][t] = a[k-1][j][t-1];

  }

  for (i = u, j = 1; j <= u; j++)

   if (a[k-1][j][1]<a[k-1][j][2])   // 若k−1划分式第1项小于第2项 

   {
    i++;               // 第1项加1为k的第i个划分式的第1项 

    a[k][i][1] = a[k-1][j][1] + 1;

    for (t = 2; t <= k-1; t++)

     a[k][i][t] = a[k-1][j][t];

   }

  i++; a[k][i][1] = k;              // k的最后一个划分式为:k=k 

  u = i;

 }

 for (j = 1; j <= u; j++)                // 输出s的所有划分式 

 {
  printf("%3d: %d=%d", j, s, a[s][j][1]);

  i = 2;

  while (a[s][j][i]>0)

  {
   printf("+%d", a[s][j][i]); i++;
  }

  printf("\n");

 }
 return 0;
}

原创粉丝点击