Skip to content

Commit b507b9c

Browse files
committed
完成第十五章
1 parent f3da506 commit b507b9c

12 files changed

+468
-10
lines changed

chap15/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# 第15章 动态规划

chap15/cut_rod.c

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/**
2+
* cut_rod.h
3+
* 钢条切割问题
4+
*/
5+
6+
#include "cut_rod.h"
7+
#include "../utils.h"
8+
#include <stdlib.h>
9+
#include <stdio.h>
10+
#include <limits.h>
11+
12+
int memoized_cut_rod_aux(int price_table[], int n, int max_table[]);
13+
14+
struct cr_slt_s {
15+
int *max_table;
16+
int *cut_table;
17+
int len;
18+
};
19+
20+
typedef struct cr_slt_s cr_slt_t;
21+
22+
void free_cr_slt(cr_slt_t slt);
23+
24+
cr_slt_t extended_bottom_up_cut_rod(int price_table[], int n);
25+
/**
26+
* 输入价格表和钢条长度,返回最佳切割方案的价格
27+
* 复杂度 O(2^n)
28+
*/
29+
int cut_rod(int price_table[], int n) {
30+
if (n == 0) {
31+
return 0;
32+
}
33+
int max = INT_MIN;
34+
for (int i = 0; i < n; i++) {
35+
int p = price_table[i] + cut_rod(price_table, n-i);
36+
if (p > max) {
37+
max = p;
38+
}
39+
}
40+
return max;
41+
}
42+
43+
int memoized_cut_rod(int price_table[], int n) {
44+
int *max_table = malloc((n+1)*sizeof(int));
45+
max_table[0] = 0;
46+
for (int i = 0; i <= n; i++) {
47+
max_table[i] = INT_MIN;
48+
}
49+
int max = memoized_cut_rod_aux(price_table, n, max_table);
50+
free(max_table);
51+
return max;
52+
}
53+
54+
int memoized_cut_rod_aux(int price_table[], int n, int max_table[]) {
55+
if (max_table[n] >= 0) {
56+
return max_table[n];
57+
}
58+
int max = INT_MIN;;
59+
if (n == 0) {
60+
max = 0;
61+
}
62+
for (int i = 1; i <= n; i++) {
63+
int p = price_table[i] + memoized_cut_rod_aux(price_table, n-i, max_table);
64+
if (p > max) {
65+
max = p;
66+
}
67+
}
68+
max_table[n] = max;
69+
return max;
70+
}
71+
72+
int bottom_up_cut_rod(int price_table[], int n) {
73+
int *max_table = malloc((n+1)*sizeof(int));
74+
max_table[0] = 0;
75+
for (int i = 1; i <= n; i++) {
76+
int max = INT_MIN;
77+
for (int j = 1; j <= i; j++) {
78+
int cur = max_table[j] + max_table[i-j];
79+
if (cur > max) {
80+
max = cur;
81+
}
82+
}
83+
max_table[i] = max;
84+
}
85+
int result = max_table[n];
86+
free(max_table);
87+
return result;
88+
}
89+
90+
void free_cr_slt(cr_slt_t slt) {
91+
free(slt.max_table);
92+
free(slt.cut_table);
93+
}
94+
95+
96+
cr_slt_t extended_bottom_up_cut_rod(int price_table[], int n) {
97+
cr_slt_t slt;
98+
slt.len = n+1;
99+
slt.max_table = malloc((n+1)*sizeof(int));
100+
slt.cut_table= malloc((n+1)*sizeof(int));
101+
slt.max_table[0] = 0;
102+
slt.cut_table[0] = 0;
103+
for (int i = 1; i <= n; i++) {
104+
int max = INT_MIN;
105+
for (int j = 1; j <= i; j++) {
106+
int cur = slt.max_table[j] + slt.max_table[i-j];
107+
if (cur > max) {
108+
max = cur;
109+
slt.cut_table[i] = j;
110+
}
111+
}
112+
slt.max_table[i] = max;
113+
}
114+
return slt;
115+
}
116+
117+
118+
void print_cut_rod_solution(int price_table[], int n) {
119+
cr_slt_t slt = extended_bottom_up_cut_rod(price_table, n);
120+
printf("%d\n", slt.max_table[n]);
121+
while (n > 0) {
122+
printf("%d ", slt.cut_table[n]);
123+
n -= slt.cut_table[n];
124+
}
125+
printf("\n");
126+
free_cr_slt(slt);
127+
}

chap15/cut_rod.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifndef CUT_ROD_H
2+
#define CUT_ROD_H
3+
4+
int cut_rod(int price_table[], int n);
5+
int memoized_cut_rod(int price_table[], int n);
6+
int bottom_up_cut_rod(int price_table[], int n);
7+
void print_cut_rod_solution(int price_table[], int n);
8+
9+
#endif

chap15/longest_common_subsequence.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/**
2+
* longest_common_subsequence.c
3+
* 最长公共子序列问题
4+
*/
5+
6+
#include "longest_common_subsequence.h"
7+
#include "../utils.h"
8+
#include <stdlib.h>
9+
#include <stdio.h>
10+
#include <string.h>
11+
12+
13+
void init_lcs_slt(lcs_slt_t *slt, int m, int n) {
14+
slt->m = m;
15+
slt->n = n;
16+
slt->c = malloc((m+1)*sizeof(int*));
17+
slt->b = malloc((m+1)*sizeof(lcs_slt_dirc_t*));
18+
for (int i = 0; i <= slt->m; i++) {
19+
slt->c[i] = malloc((n+1)*sizeof(int));
20+
slt->b[i] = malloc((n+1)*sizeof(lcs_slt_dirc_t));
21+
}
22+
for (int i = 0; i <= m; i++) {
23+
slt->c[i][0] = 0;
24+
}
25+
for (int j = 0; j <= n; j++) {
26+
slt->c[0][j] = 0;
27+
}
28+
}
29+
30+
void free_lcs_slt(lcs_slt_t *slt) {
31+
for(int i = 0; i <= slt->m; i++) {
32+
free(slt->c[i]);
33+
free(slt->b[i]);
34+
}
35+
free(slt->c);
36+
free(slt->b);
37+
}
38+
39+
lcs_slt_t lcs_length(const char *strx, const char *stry) {
40+
int m = strlen(strx);
41+
int n = strlen(stry);
42+
lcs_slt_t slt;
43+
init_lcs_slt(&slt, m, n);
44+
int **c = slt.c;
45+
lcs_slt_dirc_t **b = slt.b;
46+
for (int i = 1; i <= m; i++) {
47+
for (int j = 1; j <= n; j++) {
48+
if (strx[i-1] == stry[j-1]) {
49+
c[i][j] = c[i-1][j-1] + 1;
50+
b[i][j] = UP_LEFT;
51+
} else if (c[i-1][j] >= c[i][j-1]) {
52+
c[i][j] = c[i-1][j];
53+
b[i][j] = UP;
54+
} else {
55+
c[i][j] = c[i][j-1];
56+
b[i][j] = LEFT;
57+
}
58+
}
59+
}
60+
return slt;
61+
}
62+
63+
void print_lcs_aux(const char *strx, int i, int j, lcs_slt_dirc_t **b);
64+
65+
void print_lcs(const char *strx, const char *stry, int i, int j) {
66+
lcs_slt_t slt = lcs_length(strx, stry);
67+
lcs_slt_dirc_t **b = slt.b;
68+
print_lcs_aux(strx, i, j, b);
69+
printf("\n");
70+
free_lcs_slt(&slt);
71+
}
72+
73+
void print_lcs_aux(const char *strx, int i, int j, lcs_slt_dirc_t **b) {
74+
if (i == 0 || j == 0) {
75+
return;
76+
}
77+
if (b[i][j] == UP_LEFT) {
78+
print_lcs_aux(strx, i-1, j-1, b);
79+
printf("%c", strx[i-1]);
80+
} else if (b[i][j] == UP) {
81+
print_lcs_aux(strx, i-1, j, b);
82+
} else {
83+
print_lcs_aux(strx, i, j-1, b);
84+
}
85+
}

chap15/longest_common_subsequence.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#ifndef LONGEST_COMMON_SUBSEQUENCE_H
2+
#define LONGEST_COMMON_SUBSEQUENCE_H
3+
4+
enum lcs_slt_dirc_e {
5+
UP,
6+
LEFT,
7+
UP_LEFT
8+
};
9+
10+
typedef enum lcs_slt_dirc_e lcs_slt_dirc_t;
11+
12+
struct lcs_slt_s {
13+
int **c;
14+
lcs_slt_dirc_t **b;
15+
int m;
16+
int n;
17+
};
18+
19+
typedef struct lcs_slt_s lcs_slt_t;
20+
21+
void init_lcs_slt(lcs_slt_t *slt, int m, int n);
22+
void free_lcs_slt(lcs_slt_t *slt);
23+
lcs_slt_t lcs_length(const char *strx, const char *stry);
24+
25+
#endif

chap15/matrix_chain_multiplication.c

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* matrix_chain_multiplication.c
3+
* 矩阵链乘法问题
4+
*/
5+
6+
#include "matrix_chain_multiplication.h"
7+
#include "../utils.h"
8+
#include <stdio.h>
9+
#include <stdlib.h>
10+
#include <limits.h>
11+
12+
struct mcm_slt_s {
13+
int **s;
14+
int **m;
15+
int len;
16+
};
17+
18+
typedef struct mcm_slt_s mcm_slt_t;
19+
20+
void free_mcm_slt(mcm_slt_t slt) {
21+
for (int i = 0; i < slt.len; i++) {
22+
free(slt.m[i]);
23+
free(slt.s[i]);
24+
}
25+
free(slt.m);
26+
free(slt.s);
27+
}
28+
29+
mcm_slt_t matrix_chain_order(int p[], int n) {
30+
int len = n+1;
31+
mcm_slt_t slt;
32+
slt.s = malloc(len*sizeof(int*));
33+
slt.m = malloc(len*sizeof(int*));
34+
for (int i = 0; i < len; i++) {
35+
slt.s[i] = malloc(len*sizeof(int));
36+
slt.m[i] = malloc(len*sizeof(int));
37+
}
38+
slt.len = n+1;
39+
for (int i = 1; i < len; i++) {
40+
slt.m[i][i] = 0;
41+
}
42+
for (int l = 1; l < len; l++) {
43+
for (int i = 1; i < len-l+1; i++) {
44+
int j = i+l-1;
45+
slt.m[i][j] = INT_MAX;
46+
for (int k =i; k < j; k++) {
47+
int cur = slt.m[i][k] + slt.m[k+1][j] + p[i-1]*p[k]*p[j];
48+
if (cur < slt.m[i][j]) {
49+
slt.m[i][j] = cur;
50+
slt.s[i][j] = k;
51+
}
52+
}
53+
}
54+
}
55+
return slt;
56+
}
57+
58+
void print_optimal_parens_aux(mcm_slt_t slt, int i, int j) {
59+
if (i == j) {
60+
printf("A%d", i);
61+
} else {
62+
printf("(");
63+
print_optimal_parens_aux(slt, i, slt.s[i][j]);
64+
print_optimal_parens_aux(slt, slt.s[i][j]+1, j);
65+
printf(")");
66+
}
67+
}
68+
69+
void print_optimal_parens(int p[], int n, int i, int j) {
70+
mcm_slt_t slt = matrix_chain_order(p, n);
71+
printf("%d\n", slt.m[i][j]);
72+
print_optimal_parens_aux(slt, i, j);
73+
printf("\n");
74+
}

chap15/matrix_chain_multiplication.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef MATRIX_CHAIN_MULTIPLICATION
2+
#define MATRIX_CHAIN_MULTIPLICATION
3+
4+
void print_optimal_parens(int p[], int n, int i, int j);
5+
6+
#endif

chap15/optimal_binary_search_tree.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* optimal_binary_search_tree.c
3+
* 最优二叉搜索树
4+
*/
5+
6+
#include "optimal_binary_search_tree.h"
7+
#include "../utils.h"
8+
#include <stdlib.h>
9+
#include <limits.h>
10+
#include <float.h>
11+
#include <stdio.h>
12+
13+
void init_obst_slt(obst_slt_t *slt, int n) {
14+
slt->n = n;
15+
slt->e = malloc((n+2)*sizeof(double*));
16+
slt->r = malloc((n+2)*sizeof(int*));
17+
for (int i = 1; i < n+2; i++) {
18+
slt->e[i] = malloc((n+1)*sizeof(double));
19+
slt->r[i] = malloc((n+1)*sizeof(int));
20+
}
21+
}
22+
23+
void free_obst_slt(obst_slt_t *slt) {
24+
int n = slt->n;
25+
for (int i= 1; i < n+2; i++) {
26+
free(slt->e[i]);
27+
free(slt->r[i]);
28+
}
29+
free(slt->e);
30+
free(slt->r);
31+
}
32+
33+
obst_slt_t optimal_bst(double p[], double q[], int n) {
34+
obst_slt_t slt;
35+
init_obst_slt(&slt, n);
36+
double **e = slt.e;
37+
int **root = slt.r;
38+
double w[n+2][n+1];
39+
for (int i = 1; i < n+2; i++) {
40+
e[i][i-1] = q[i-1];
41+
w[i][i-1] = q[i-1];
42+
}
43+
for (int l = 1; l <= n; l++) {
44+
for (int i = 1; i <= n-l+1; i++) {
45+
int j = i+l-1;
46+
e[i][j] = DBL_MAX;
47+
w[i][j] = w[i][j-1] + p[j] + q[j];
48+
for (int r = i; r <= j; r++) {
49+
double cur = e[i][r-1] + e[r+1][j] + w[i][j];
50+
if (cur < e[i][j]) {
51+
e[i][j] = cur;
52+
root[i][j] = r;
53+
}
54+
}
55+
}
56+
}
57+
printf("%lf\n", e[1][n]);
58+
return slt;
59+
}
60+
61+
void print_obst(double p[], double q[], int i, int j) {
62+
63+
}

0 commit comments

Comments
 (0)