# Leetcode Triangle

#### 2022-07-20 22:59

> ##### Algorithms:
>
> #algorithm #dynamic_programming
>
> ##### Difficulty:
>
> #coding_problem #difficulty-medium
>
> ##### Additional tags:
>
> #leetcode
>
> ##### Revisions:
>
> N/A

##### Related topics:

##### Links:

- [Link to problem](https://leetcode.com/problems/triangle/)

---

### Problem

Given a `triangle` array, return _the minimum path sum from top to bottom_.

For each step, you may move to an adjacent number of the row below. More formally, if you are on index `i` on the current row, you may move to either index `i` or index `i + 1` on the next row.

#### Examples

**Example 1:**

```
**Input:** triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
**Output:** 11
**Explanation:** The triangle looks like:
   2
  3 4
 6 5 7
4 1 8 3
The minimum path sum from top to bottom is 2 + 3 + 5 + 1 = 11 (underlined above).
```

**Example 2:**

```
**Input:** triangle = [[-10]]
**Output:** -10
```

#### Constraints

- `1 <= triangle.length <= 200`
- `triangle[0].length == 1`
- `triangle[i].length == triangle[i - 1].length + 1`
- `-104 <= triangle[i][j] <= 104`

### Thoughts

> [!summary]
> This is a #dynamic_programming problem.

Same as in [[Leetcode House-Robber]], there are four stages to optimization:

#### Stage 1: ordinary recursion

#### Stage 2: recursion with cachinqg

### Solution

#### Stage 2:

```cpp
class Solution {
  vector<vector<int>> cache;
  int minimum(vector<vector<int>> &triangle, int level, int l, int r) {
    if (level == 0) {
      return triangle[0][0];
    } else {
      int minLen = INT_MAX;
      for (int i = l; i <= r; i++) {
        if (i < 0 || i > level) {
          continue;
        }
        if (cache[level][i] != -1) {
          minLen = min(cache[level][i], minLen);
          // cout<<"Using cache: "<<minLen<<" for "<<level<<", "<<i<<'\n';
        } else {
          cache[level][i] =
              triangle[level][i] + minimum(triangle, level - 1, i - 1, i);
          minLen = min(cache[level][i], minLen);
        }
      }
      // cout<<minLen<<", "<<level<<'\n';
      return minLen;
    }
  }

public:
  int minimumTotal(vector<vector<int>> &triangle) {
    // Stage one: recursive
    cache =
        vector<vector<int>>(triangle.size(), vector<int>(triangle.size(), -1));
    return minimum(triangle, triangle.size() - 1, 0, triangle.size() - 1);
  }
};
```
