矩阵连乘
题目描述
解题代码
void printOptimalParens(vector<vector<int>>& partition, int i, int j) {
if (i == j) cout << "A" << i;
else {
cout << "(";
printOptimalParens(partition, i, partition[i][j]);
printOptimalParens(partition, partition[i][j] + 1, j);
cout << ")";
}
}
int matrixChainOrder(vector<int>& nums) {
int n = nums.size() - 1;
vector<vector<int>> dp(n + 1, vector<int>(n + 1, INT32_MAX));
vector<vector<int>> partition(n + 1, vector<int>(n + 1));
for (int i = 1; i <= n; ++i) {
dp[i][i] = 0;
}
for (int len = 2; len <= n; ++len) {
for (int i = 1; i + len - 1 <= n; ++i) {
int j = i + len - 1;
for (int k = i; k <= j - 1; ++k) {
int sum = dp[i][k] + dp[k + 1][j] + nums[i - 1] * nums[k] * nums[j];
if (sum < dp[i][j]) {
dp[i][j] = sum;
partition[i][j] = k;
}
}
}
}
printOptimalParens(partition, 1, n);
return dp[1][n];
}
最长公共子序列
题目描述
解题代码
void printLCS(const string& text1, vector<vector<char>>& dir, int i, int j) {
if (i == 0 || j == 0) return;
if (dir[i][j] == 'S') {
printLCS(text1, dir, i - 1, j - 1);
cout << text1[i - 1];
}
else if (dir[i][j] == 'U') {
printLCS(text1, dir, i - 1, j);
}
else {
printLCS(text1, dir, i, j - 1);
}
}
int longestCommonSubsequence(string text1, string text2) {
int m = text1.size(), n = text2.size();
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
vector<vector<char>> dir(m + 1, vector<char>(n + 1, '*'));
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
if (text1[i - 1] == text2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
dir[i][j] = 'S';
}
else if (dp[i - 1][j] >= dp[i][j - 1]) {
dp[i][j] = dp[i - 1][j];
dir[i][j] = 'U';
}
else {
dp[i][j] = dp[i][j - 1];
dir[i][j] = 'L';
}
}
}
printLCS(text1, dir, m, n);
return dp[m][n];
}
最大子段和
题目描述
解题代码
分治法
int dividedMaxSubSum(vector<int>& nums, int left, int right) {
if (left == right) return nums[left];
int mid = left + (right - left) / 2;
int lSum = dividedMaxSubSum(nums, left, mid);
int rSum = dividedMaxSubSum(nums, mid + 1, right);
int midL = 0, maxMidL = INT32_MIN;
for (int i = mid; i >= left; --i) {
midL += nums[i];
maxMidL = max(maxMidL, midL);
}
int midR = 0, maxMidR = INT32_MIN;
for (int i = mid + 1; i <= right; ++i) {
midR += nums[i];
maxMidR = max(maxMidR, midR);
}
return max(maxMidL + maxMidR, max(lSum, rSum));
}
int maxSubSum(vector<int>& nums) {
int n = nums.size();
return dividedMaxSubSum(nums, 0, n - 1);
}
动态规划
int maxSubSum(vector<int>& nums) {
int res = 0, sum = 0;
for (int i = 0; i < nums.size(); ++i) {
if (sum > 0) {
sum += nums[i];
}
else {
sum = nums[i];
}
res = max(res, sum);
}
return res;
}
凸多边形最优三角剖分
题目描述
解题代码
int minScoreTriangulation(vector<int>& values) {
int n = values.size();
vector<vector<int>> dp(n, vector<int>(n, 0));
for (int len = 3; len <= n; ++len) {
for (int i = 0; i + len - 1 < n; ++i) {
int j = i + len - 1;
dp[i][j] = INT32_MAX;
for (int k = i + 1; k < j; ++k) {
int cost = dp[i][k] + dp[k][j] + values[i] * values[j] * values[k];
dp[i][j] = min(dp[i][j], cost);
}
}
}
return dp[0][n - 1];
}
0-1背包问题
题目描述
解题代码
int knapsack01(vector<int>& weights, vector<int>& values, int c) {
int n = weights.size();
vector<vector<int>> dp(n, vector<int>(c + 1, 0));
for (int j = weights[0]; j <= c; ++j) {
dp[0][j] = values[0];
}
for (int i = 1; i < n; ++i) {
for (int j = 1; j <= c; ++j) {
dp[i][j] = dp[i - 1][j];
if (j >= weights[i]) {
dp[i][j] = max(dp[i][j], dp[i - 1][j - weights[i]] + values[i]);
}
}
}
return dp[n - 1][c];
}
最优二叉搜索树
题目描述
解题代码
double optimalBST(vector<double>& pNonLeaves, vector<double>& pLeaves) {
int n = pNonLeaves.size() - 1;
vector<vector<double>> dp(n + 2, vector<double>(n + 1, DBL_MAX));
vector<vector<int>> root(n + 1, vector<int>(n + 1));
vector<vector<double>> pSum(n + 2, vector<double>(n + 1));
for (int i = 1; i <= n + 1; ++i) {
dp[i][i - 1] = pLeaves[i - 1];
pSum[i][i - 1] = pLeaves[i - 1];
}
for (int len = 1; len <= n; ++len) {
for (int i = 1; i + len - 1 <= n; ++i) {
int j = i + len - 1;
pSum[i][j] = pSum[i][j - 1] + pNonLeaves[j] + pLeaves[j];
for (int r = i; r <= j; ++r) {
double cost = dp[i][r - 1] + dp[r + 1][j] + pSum[i][j];
if (cost < dp[i][j]) {
dp[i][j] = cost;
root[i][j] = r;
}
}
}
}
return dp[1][n];
}