全排列与整数划分算法分析

来源:互联网 发布:百度地图路网数据提取 编辑:程序博客网 时间:2024/05/21 07:46

1.全排列算法
题目:求出1-n的全排列.

思想:交换第1个元素与第i个元素,得到n个序列;把每个序列分成两部分:第一个元素,其余的元素;对其余元素执行全排列操作,记得操作完后,将这两个元素交换回来,以方便下面的交换.

算法实现:

void Swap(int a, int b) // 交换a和b {    int temp = a;     a = b;     b = temp; } void Perm(int list[], int k, int m) //生成list [k:m ]的所有排列方式{      int i;     if (k == m)     {         for (i = 0; i <= m; i++)             putchar(list[i]);         putchar('\n');     }       else            //递归        for (i=k; i <= m; i++) {             Swap (list[k], list[i]);             Perm (list, k+1, m);             Swap (list [k], list [i]);         } } 

注:此算法没有考虑重复性

2.整数划分
题目:将正整数n表示成一系列整数之和,在正整数n的所有不同划分中,将最大加数n1不大于m的划分个数记做split(n,m).

思想:
(1)当n = 1或m = 1时,split的值为1,可根据上例看出,只有一个划分1 或 1 + 1 + 1 + 1 + 1 + 1,可用程序表示为if(n == 1 || m == 1) return 1;
(2) m > n
在整数划分中实际上最大加数不能大于n,因此在这种情况可以等价为split(n, n);
(3) m = n
这种情况可用递归表示为split(n, m - 1) + 1,从以上例子中可以看出,就是最大加数为6和小于6的划分之和
(4) m < n
这是最一般的情况,在划分的大多数时都是这种情况。
从上例可以看出,设m = 4,那split(6, 4)的值是最大加数小于4划分数和整数2的划分数的和。因此,split(n, m)可表示为split(n, m - 1) + split(n - m, m).

算法实现:

int split(int n, int m)   {      if(n < 1 || m < 1) return 0;      if(n == 1 || m == 1) return 1;      if(n < m) return split(n, n);      if(n == m) return (split(n, m - 1) + 1);      if(n > m) return (split(n, m - 1) + split((n - m), m));  }
1 0
原创粉丝点击