分治法:算法依次或多次地递归调用自身来解决相关的子问题
上楼梯问题:一次只能走1步或2步,上n阶楼梯,有几种上法
斐波那契数列
动态规划:把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解,
典型例题:LCS,编辑距离,01背包问题
LCS: i==0||j==0 c[i][j]=0;
i>0 j>0 x[i]=y[j] c[i][j] = c[i-1][j-1] +1
i>0 j> 0 x[i] != y[j] c[i][j] = max{ c[i, j-1] ,c[i-1][j] }
#include <stdio.h> #include <stdlib.h> #include <string.h> int LCS(char *, char *); int main(int argc, const char *argv[]) { char *s1 = "djasdhak"; char *s2 = "dyjak"; int ret = LCS(s1, s2); printf("%d\n", ret); return 0; } int LCS(char *s1, char *s2) { int len1 = strlen(s1); int len2 = strlen(s2); int cnt[ len1 + 1][ len2 + 1]; int i,j; for(i = 0; i < len1 + 1 ; i++) for(j = 0; j < len2 + 1; j++) if(i==0 || j==0) cnt[i][j] = 0; for(i = 1; i <= len1; ++i) for(j = 1; j <= len2; ++j) { if(s1[i-1] == s2[j-1]) cnt[i][j] = cnt[i-1][j-1] + 1; else { cnt[i][j] = cnt[i-1][j] > cnt[i][j-1] ? cnt[i-1][j] : cnt[i][j-1]; } } return cnt[len1][len2]; }
编辑距离:http://www.cnblogs.com/wj9012/p/3919592.html
i==0 c[i][j] = j
j==0 c[i][j] = i
s1[i-1] == s2[j-1] c[i][j] = c[i-1][j-1]
s1[i-1] != s2[j-1] c[i][j] = min{ c[i-1][j-1], c[i][j-1], c[i-1][j] }
01背包问题:
j < c[i] f[i][j]=f[i-1][j] -->物体i重量比背包容量大
max{ f[i-1][j], f[i-1][j-c[i] ] +w[i] } -->选取放入i和不放入i的最大值
//01背包问题,3件物品,背包容纳5kg,物体1重1kg价值60元,物体2重2kg价值100元,物体3重3kg价值120元,怎么最大化背包所装价值
#include <stdio.h> #include <stdlib.h> #include <string.h> int backbag(int [][6], int *, int *, int); int main(int argc, const char *argv[]) { int N = 3; int V = 5; int C[4] = {0, 1, 2, 3}; int W[4] = {0, 60, 100, 120}; int f[N+1][V+1]; int ret = backbag(f, C, W, N+1); printf("%d\n", f[N][V]); return 0; } int backbag(int p[][6], int *c, int *w, int N) { int i, j; for(i = 0; i < 6; ++i) p[0][i] = 0; for(i = 1; i < N; ++i) { p[i][0] = 0; for(j = 1; j < 6; ++j ) { if(j < c[i]) { p[i][j] = p[i-1][j]; } else { p[i][j] = (p[i-1][j] > (p[i-1][j-c[i]] + w[i]) ? p[i-1][j] : (p[i-1][j-c[i]] + w[i]) ); } } } }