-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdynamicprogramming.h
More file actions
200 lines (185 loc) · 4.05 KB
/
dynamicprogramming.h
File metadata and controls
200 lines (185 loc) · 4.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#ifndef DP_H_
#define DP_H_
#include <map>
#include <iostream>
#include <string>
#include <stack>
using namespace std;
/*动态规划求解步骤:1.刻画一个最优解的结构特征
2.递归地定义最优解的值
3.计算最优解的值,通常采用自底向上的方法
4.利用计算出的信息构造一个最优解
*/
//pi的值数组
int p[7] = { 30, 35, 15, 5, 10, 20, 25 };
std::string sourceData[6] = { "A1", "A2", "A3", "A4", "A5", "A6" };
void matrixchain(int **m, int **s, int n) {
//用于保存最小的值
long long int q = 0;
//初始化
for (int i = 0; i < n; ++i) {
m[i][i] = 0;
}
for (int l = 2; l <= n; ++l) {
//保存疑问:这个n-l + 1到底是个什么鬼
for (int i = 0; i < n - l + 1; ++i) {
int j = i + l - 1;
//INT_MAX这个b竟然有2的31次方那么大,你咋不上天呢???
m[i][j] = m[i + 1][j] + p[i] * p[i + 1] * p[j + 1];
s[i][j] = i;
/* std::cout << m[i][j];*/
for (int k = i + 1; k < j; ++k) {
//这么加的话。。会溢出。我的个乖乖
q = m[i][k] + m[k + 1][j] + p[i] * p[k + 1] * p[j + 1];
if (q < m[i][j]) {
m[i][j] = q;
s[i][j] = k;
}
}
}
}
}
//递归的打印出结果
void traceBack(int **s, int i, int j) {
if (i == j) {
std::cout << sourceData[i];
return;
}
else {
std::cout << "(";
traceBack(s, i, s[i][j]);
traceBack(s, s[i][j] + 1, j);
std::cout << ")";
}
}
//非递归算法输出
void printAnswer(int **s, int n) {
int size = 1;
std::stack<int> left;
stack<int> right;
stack<int> info; //info的值表示是第一个调用还是第二个调用 0表示第一个调用。1表示第二个调用
left.push(0);
right.push(5);
info.push(0);
int k = 0;
while (!left.empty() && !right.empty()) {
//这里调用的是第一个函数
if (left.top() == right.top()) {
//之前调用的是第一个
if (info.top() == 0) {
cout << sourceData[left.top()];
left.pop();
right.pop();
info.pop();
//第一个函数返回的时候 入口变为第二个函数,所以栈顶的标志要改成1
//函数返回调用第二个
if (!info.empty()) {
info.pop();
info.push(1);
}
left.push(s[left.top()][right.top()] + 1);
right.push(right.top());
info.push(1);
}
else {
while (!info.empty()) {
if (info.top() == 1) {
if (left.top() == right.top()) {
cout << sourceData[left.top()];
left.pop();
right.pop();
info.pop();
}
else {
left.pop();
right.pop();
info.pop();
cout << ")";
}
}
else {
break;
}
}
//调用第二个
if (!left.empty() && !right.empty()) {
left.push(s[left.top()][right.top()] + 1);
right.push(right.top());
if (!info.empty()) {
info.pop();
info.push(1);
info.push(1);
}
}
else {
break;
}
}
continue;
}
while (!left.empty() && !right.empty() && left.top() != right.top()) {
cout << "(";
//k = s[left.top()][right.top()];
//这里应该是两边都要push的
//调用第一个
left.push(left.top());
right.push(s[left.top()][right.top()]);
if (!info.empty()) {
info.pop();
info.push(0);
}
info.push(0);
}
if (left.top() == right.top()) {
//如果两个相等的话。直接进入判断部分
continue;
}
//调用第二个
left.push(s[left.top()][right.top()] + 1);
right.push(right.top());
if (!info.empty()) {
info.pop();
info.push(1);
info.push(1);
}
}
}
////递归返回。不管是不是都要退栈,判断函数在第一个地方有
//while (size) {
// if (left.top() == right.top()) {
// cout << sourceData[left.top()];
// left.pop();
// right.pop();
// }
// else {
// cout << ")";
// left.pop();
// right.pop();
// }
//}
//left.push(s[left.top()][right.top()] + 1);
//right.push(right.top());
//非递归地打印出最优的解:使用栈
//优先计算s[0,5]的值为2,从0到2将字符push进栈
//然后计算s[0,2]的值为0, pop第一个,
//
void printBestAnswer(int **s, int n) {
int k = s[0][n - 1];
int left = 0;
int right = 0;
std::stack<int> position;
position.push(k);
while (position.empty()) {
k =
left = s[0][k];
right = s[k + 1][n - 1];
}
std::stack<std::string> stack;
for (int i = k; i >= 0; --i) {
stack.push(sourceData[i]);
}
std::cout << "(";
std::string hehe = stack.top();
std::cout << hehe;
}
#endif DP_H_