### Question

Given an array of integers A, give an algorithm to find the longest Arithmetic progression in it, i.e find a sequence i1 < i2 < … < ik, such that

A[i1], A[i2], …, A[ik] forms an arithmetic progression, and k is the largest possible.

The sequence S1, S2, …, Sk is called an arithmetic progression if S(j+1) – S(j) is a constant.

### Solution

**This is a rather difficult Arithmetic Progression question**.

The solution is 2-D DP.

The idea is to create a 2D table dp[n][n]. An entry dp[i][j] in this table stores LLAP with input[i] and input[j] as first two elements of AP(j > i).

The last column of the table is always 2. Rest of the table is filled

from bottom right to top left.To fill rest of the table, j (second element in AP) is first fixed. i and k are searched for a fixed j. If i and k are found such that i, j, k form an AP, then

the value of dp[i][j] is set as dp[j][k] + 1.

Note that the value of dp[j][k] must have been filledbefore as the loop traverses from right to left columns.

The 2 difficult points of this question:

- how to come up with the transation formula. (i.e.
**dp[i][j] = dp[j][k] + 1**, when (i, j, k) forms a AP). - how to fill up all dp[i][j] in each loop of j. (Once inside the if-else, once outside the main while-loop)

### Code

**written by me**

```
public int longest(int[] A) {
int len = A.length;
int[][] dp = new int[len][len];
for (int i = 0; i < len; i++) {
// the pair ending at last position is always a progression
dp[i][len - 1] = 2;
}
int longest = 1;
for (int j = len - 2; j >= 0; j--) {
// for each j, find i and k that makes 1 progression
int i = j - 1;
int k = j + 1;
while (i >= 0 && k < len) {
int total = A[i] + A[k];
if (total > 2 * A[j]) {
// this is important!
dp[i][j] = 2;
i--;
} else if (total < 2 * A[j]) {
k++;
} else {
// found a valid progression triplet A(i, j, k)
dp[i][j] = dp[j][k] + 1;
longest = Math.max(longest, dp[i][j]);
i--;
k++;
}
}
// this is important!
while (i >= 0) {
dp[i][j] = 2;
i--;
// If the loop was stopped due to k becoming more than
// n-1, set the remaining dp[i][j] as 2
}
}
return longest;
}
```