```java =
class Solution {
// Edit Distance
// dp(i, j) : 把 A[0~i] B[0~j] 變成相同的最小 cost
// 轉移:
// 1. i, j 保留 dp(i-1, j-1) if A[i] = B[j]
// 2. 刪除 i : dp(i-1, j) + cost(A[i])
// 3. 刪除 j : dp(i, j-1) + cost(B[j])
// 找出最小 cost 也就等於找出保留最多相等
// 找出最小 cost 也就等於找出保留最多相等
public int minimumDeleteSum(String s1, String s2) {
int n = s1.length();
int m = s2.length();
int dp[][] = new int [n + 1][m + 1];
for(int i = 0; i <= n; i++){
Arrays.fill(dp[i], Integer.MAX_VALUE/2);
}
dp[0][0] = 0;
for(int i = 1; i <= n; i++){
dp[i][0] = dp[i - 1][0] + (int) s1.charAt(i - 1);
}
for(int i = 1; i <= m; i++){
dp[0][i] = dp[0][i - 1] + (int) s2.charAt(i - 1);
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(s1.charAt(i - 1) == s2.charAt(j - 1)){
dp[i][j] = dp[i - 1][j - 1];
}else{
dp[i][j] = Math.min(dp[i - 1][j - 1] + (int) s2.charAt(j - 1) + (int) s1.charAt(i - 1), dp[i][j]);
dp[i][j] = Math.min(dp[i][j - 1] + (int) s2.charAt(j - 1), dp[i][j]);
dp[i][j] = Math.min(dp[i - 1][j] + (int) s1.charAt(i - 1), dp[i][j]);
}
}
}
return dp[n][m];
}
}
```
### LeetCode 1062
```
lcp(i, j) : suffix[i] 和 suffix[j] 的 longest common prefix
lcp(i, j) = lcp(i+1, j+1) + 1 if (s[i] = s[j])
= 0 else
lcp(i, j) = lcp(i-1, j-1) - 1
suf[0] : aab]caabdaab
suf[4] : aab]daab
suf[1] : ab]caabdaab
suf[5] : ab]daab
每個 substring 都是某個 suffix 的 prefix
```
### 887. Super Egg Drop
```
class Solution {
// 狀態數量: O(k * n), k = 100, n = 10000
// 轉移時間: O(n) -> O(log n)
// time : O(k * n log n)
public int superEggDrop(int k, int n) {
if (k == 1) return n;
int ans = n;
// binary search
// while (...)
int lower = superEggDrop(k - 1, h - 1); // 往下需要的次數
int higher = superEggDrop(k, n - h); // 往上需要的次數
int v = max(lower, higher);
ans = min(ans, v + 1);
return ans;
}
// time : O(k * n^2)
/* slow
public int superEggDrop(int k, int n) {
if (k == 1) return n;
int ans = n;
for (int h = 1; h <= n; h++) {
int lower = superEggDrop(k - 1, h - 1); // 往下需要的次數
int higher = superEggDrop(k, n - h); // 往上需要的次數
int v = max(lower, higher);
ans = min(ans, v + 1);
}
return ans;
}
*/
}
/*
k 個蛋, n 層樓, 最少要試幾次?
dp(k, t) : k 個蛋,t 次,最多可以測多少層樓
dp(1, t) = t
dp(k, t) = dp(k-1, t-1) + dp(k, t-1) + 1
- 有破 dp(1, t-1) ans 介於 [0, h-1]
- 沒有破 dp(2, t-1): ans 介於 [h, h+dp(2,t-1)]
dp(1, 1) = 1
dp(1, 2) = 2
dp(1, 3) = 3
dp(1, 1) = dp(1, 1) = 1
dp(2, 2) = dp(2, 1) + dp(1, 1) + 1 = 3
dp(2, 3) = dp(2, 2) + dp(1, 2) + 1 = 3 + 2 + 1 = 6
dp(2, 4) = dp(2, 3) + dp(1, 3) + 1 = 6 + 3 + 1 = 10
dp(2, 5) = dp(2, 4) + dp(1, 4) + 1 = 10 + 4 + 1 = 15
第一次丟 h = 3
dp(3, 2) = dp(2, 2) = 3
dp(3, 3) = dp(3, 2) + dp(2, 2) + 1 = 7
dp(3, 4) = dp(3, 3) + dp(2, 3) + 1 = 7 + 6 + 1 = 14
*/
```