摘要:比如,4=1+1+1+1=1+1+2=1+2+1=1+3=2+1+1=2+2=3+1=4总共有8种方法,一般的,证书n有2n-1种划分方法,可以设计一种方法,按照字典序将所有的划分方法都输出来。其中的思路为,给定一个n,使用一个长度为n的数组,初始化每个元素为1,每次将低位的元素分出一个元素出来,加到相邻的高位上面。 1 void part(int n, int* as, void (*fn)(int,int*)) 2 { 3 int j; 4 int i; 5 for(j=0;j<n;j++) 6 as[j]=1...
阅读全文
摘要:给定一个序列a1,a2,...,an,求子序列中和最大的那个。如果使用暴力算法,需要使用O(n2)的时间复杂度。使用动态规划可以将时间复杂度下降到O(n),具体方法如下:定义bi为以ai结尾的所有序列中最大值,显然max{b1,b2,b3,...,bn}就是子序列和的最大值,bi满足关系式b1=a1bi=max{bi-1+ai, ai}通过这个关系式,可以在O(n)的时间内把所有bi求出来,然后求最大值就可以了。注意到bi只有在求bi+1以及求最大值的时候才用到,我们也可以把这两个过程合并起来。维护一个当前子序列和最大值,如果bi比最大值还大,则更新最大值,这样数组bi实际上也不需要了。
阅读全文
摘要:递归算法比较简单vector<string> p(string s){ vector<string> result; if(s.size() == 1) { result.push_back(s); return result; } for(int i=0;i<s.size();i++) { char c=s[i]; string subs=s; subs.erase(i,1); vector<string> t=p(subs); for(int i=0;i<t.size();i++) result.push_back(t[i].append(1
阅读全文
摘要:quick sort的思想是使用一个元素将表分成2个部分,其中一个部分是比改元素小,另外一部分是大于等于该元素。在scheme里面实现起来相当直观(define (qsort p lst) (if (null? lst) '() (let ((e (car lst)) (rest (cdr lst))) (let ((less (filter (lambda (x) (p x e)) rest)) (great (filter (lambda (x) (not (p x e))) rest))) (append (qsort p less) (cons e (qsort p great
阅读全文
摘要:merge sort的思想很简单,首先将表均匀分成2份,然后每份都是递归使用merge sort来排序,最后使用一个线性合并的方法来合并两个有序表。为此我们首先定义的是split-evenly,用来切分一个list(define (split-evenly lst) (if (null? lst) (list '() '()) ;空表的话返回两个空表 (let* ((h (car lst)) (rest (cdr lst)) (len (length lst)) (sp (split-evenly rest)) (first (car sp)) (second (cadr sp
阅读全文