11---
2- created : 2025/3/19 17:19:15
3- modified : 2025/5/06 14:19:10
2+ description :
3+ aliases :
4+ created : 2025-05-18
5+ modified : 2025-05-23
46tags :
57 - review
68references :
7- - https://github.com/crapas/dp
9+ - https : //github.com/crapas/dp
810---
11+
912- DP 문제 풀이 조건
1013 - **최적 부분 구조, 최적 하위 구조 (Optimal Substructure)**
1114 - *크기가 n인 문제*에서, 문제 해결 형태는 같지만 *n 미만의* 원소를 가지는, 더 작은 크기의 문제의 풀이법을 사용하는 것이 최적의 풀이법에 해당하면 이를 optimal substructure
@@ -114,8 +117,8 @@ references:
114117 - 다르면
115118 - $dp[i][j] = \min(dp[i - 1][j - 1],\; dp[i - 1][j],\; dp[i][j - 1]) + 1$
116119 - 위쪽 셀, 왼쪽 셀, 왼쪽 위 셀의 값의 최솟 값 + 1
117- $target = dp[ m] [ n ] $
118- ![ [ image-DP-4.png]]
120+ - $target = dp[m][n]$
121+ - ![[image-DP-4.png]]
119122- [[ 다이내믹 프로그래밍 완전 정복]] p.130
120123
121124## 직사각형에서 총 경로 수 구하기
@@ -267,12 +270,13 @@ $target = dp[m][n]$
267270 - $i$번째 물건을 선택했을 때 최대가격
268271 - `value[i - 1] + maxValue[i - 1][j - weight[i - 1]]`
269272 - $j$ 선택한 물건의 무게를 뺀 위치 즉, 남은 용량
270- ```cpp
271- dp[i][w] = max(
272- dp[i-1][w], // i번째 물건을 선택하지 않음
273- dp[i-1][w - weight[i]] + value[i] // i번째 물건을 선택함
274- )
275- ```
273+ -
274+ ```cpp
275+ dp[i][w] = max(
276+ dp[i-1][w], // i번째 물건을 선택하지 않음
277+ dp[i-1][w - weight[i]] + value[i] // i번째 물건을 선택함
278+ )
279+ ```
276280 - ![[image-DP-15.png]]
277281- [[ 다이내믹 프로그래밍 완전 정복]] p.182
278282
@@ -285,22 +289,23 @@ $target = dp[m][n]$
285289- $B_ {n} = S[ n] + S[ n - 1] + MAX(A_ {n - 3},\; B_ {n - 3})$
286290
287291## LIS (최장 증가 부분 수열 길이 구하기)
288- ``` cpp
289- int n;
290- cin >> n;
291- vector<int > a (n), dp(n, 1);
292- for (int i = 0; i < n; i++) cin >> a[ i] ;
293-
294- for (int i = 1; i < n; i++) {
295- for (int j = 0; j < i; j++) {
296- if (a[ j] < a[ i] ) {
297- dp[ i] = max(dp[ i] , dp[ j] + 1);
298- }
299- }
300- }
301-
302- cout << * max_element(dp.begin(), dp.end());
303- ```
292+ -
293+ ```cpp
294+ int n;
295+ cin >> n;
296+ vector<int> a(n), dp(n, 1);
297+ for (int i = 0; i < n; i++) cin >> a[i];
298+
299+ for (int i = 1; i < n; i++) {
300+ for (int j = 0; j < i; j++) {
301+ if (a[j] < a[i]) {
302+ dp[i] = max(dp[i], dp[j] + 1);
303+ }
304+ }
305+ }
306+
307+ cout << *max_element(dp.begin(), dp.end());
308+ ```
304309- ` dp[i] ` 는 ` a[i] ` 를 마지막 원소로 갖는 LIS의 길이
305310- 현재 글자의, 이전 글자들 대소 비교로, dp 업데이트
306311 - 이미 왼쪽부터 dp가 정복하니 최적해 보장
0 commit comments