转载原书代码:
class Solution {
public:
vector<int> diffWaysToCompute(string input) {
vector<int> data;
vector<char> ops;
int num = 0;
char op = ' ';
istringstream ss(input+"+" );(ss读取的时候是一个数字一个符号成对读入,如果不加入加号最后一个数字会读不进去,使得结果错误)
while (ss >> num && ss >> op) {
data.push_back(num);
ops.push_back(op);
}
int n = data.size();
vector<vector<vector<int>>> dp(n, vector<vector<int>>(n, vector<int>()));
for (int i = 0; i < n; ++i) {
for (int j = i; j >= 0; --j) {
if (i == j) {
dp[j][i].push_back(data[i]);
} else {
for (int k = j; k < i; k += 1) {
for (auto left : dp[j][k]) {
for (auto right : dp[k+1][i]) {
int val = 0;
switch (ops[k]) {
case '+': val = left + right; break;
case '-': val = left - right; break;
case '*': val = left * right; break;
}
dp[j][i].push_back(val);
}
}
}
}
}
}
return dp[0][n-1];
}
};
关于dp数组的初始化顺序
显然是要自下而上的 而如何把这四个字落到纸上呢
为什么三层循环要如此构建,参数初始化原理
Dp数组的初始化类似与杨辉三角(动态规划)思想,从数组的左端逐步遍历到右端,设算法进行到第n层,dp[0][0]到dp[n-1][n-1]之间的值已经全部赋值成功,如果要从(dp[n-1][n])方向开始初始化(即初始化j=i))),我们可以通过红一(n-1到n-1的全部计算组合)加红二(n本身能组成的计算组合),如果从dp[0][n]方向开始初始化(即初始化j=0),则需要计算黄一(dp[0][0])和绿二(dp[1][n]),由于红二是n自己加自己,可以计算出来,而绿二是1到n间的所有计算组合,无法直接计算出来
本文仅做学习用途,如涉及侵权请联系删除