Skip to content

Commit

Permalink
add: 2024-autumn-exercise/dp.md
Browse files Browse the repository at this point in the history
  • Loading branch information
m4ushold committed Nov 12, 2024
1 parent 3301616 commit e683da2
Showing 1 changed file with 278 additions and 0 deletions.
278 changes: 278 additions & 0 deletions slides/2024-autumn-exercise/dp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
---
marp: true
---

# Dynamic Programming
소프트웨어학부 진민성

---

# 쉬운 계단 수

## 요약
이 수는 인접한 모든 자리의 차이가 1이다. 이런 수를 계단 수라고 한다.
N이 주어질 때, 길이가 N인 계단 수가 총 몇 개 있는지 구해보자

## 제한
$1\leq N \leq 100, N \in \mathbb{N}$

---

## 풀이
DP[i][j]를 i로 끝나는 j자리 계단수의 개수라고 하자.
- $1 \leq i \leq 8$
$DP[i][j] = \sum DP[i-1][j-1] + DP[i+1][j-1]$
- $i==0$
$DP[i][j] = DP[i+1][j-1]$
- $i==9$
$DP[i][j] = DP[i-1][j-1]$

---

# 가장 긴 증가하는 부분 수열 4

## 요약
수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구해라

## 제한
수열 $A$의 크기 $N (1 ≤ N ≤ 1,000)$
$(1 ≤ Ai ≤ 1,000)$

---

## 풀이
N제한이 1000이므로 N^2풀이가 가능하다.
$DP[i]$를 $i$번째 까지의 가장 긴 증가하는 부분수열의 길이라고하자.
이전 배열을 보면서 A[i]보다 작은 수 중에 가장 큰 증가하는 부분수열의 길이+1을 DP[i]로 계산해주면 된다.
$DP[i] = (\max _{j=1}^{i-1}{DP[j]}) +1, where A[j] < A[i]$


binary search 혹은 segment tree를 이용하여 O(NlogN)에 푸는 방법또한 존재한다.
https://www.acmicpc.net/problem/14003

---

# LCS 2

## 요약
두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제

## 제한
문자열은 알파벳 대문자로만 이루어져 있으며, 최대 1000글자로 이루어져 있다.

---

## 풀이
단순하게 LCS를 구해주면 되는 문제
http://boj.kr/bd070e3638e640be9025c79ce86c9e8d

---

# 1학년

## 요약
숫자가 주어졌을 때, 상근이가 만들 수 있는 올바른 등식의 수를 구하는 프로그램을 작성하시오.

## 제한
첫째 줄에 숫자의 개수 N이 주어진다.
(3 ≤ N ≤ 100) 둘째 줄에는 0 이상 9 이하의 정수 N개가 공백으로 구분해 주어진다.
상근이는 아직 학교에서 음수를 배우지 않았고, 20을 넘는 수는 모른다.
답은 $2^{63}-1$이하임이 보장된다.

---

## 풀이

상근이는 20이상의 수를 모른다는 조건이 있으므로 1~20사이의 수의 개수만을 확인하면 된다.
$DP[i][j]$를 i개의 수를 사용하여 j를 만드는 경우의 수라고 가정해자.

$DP[i][j] = DP[i-1][j-A[i]] + DP[i-1][j+A[i]], where 1 \leq j \leq 20$


---

# 배수 찾기

## 요약
양의 정수 n이 주어졌을 때, n의 배수 중에서 0과 1로만 이루어진 m을 찾는 프로그램을 작성하시오. n은 200을 넘지 않고, m은 0보다 큰 양의 정수이며, 100자리를 넘지 않아야 한다.

## 제한
$N \leq 200$
$M \gt 0$
M은 100자리를 넘지 않아야 한다.

---

## 풀이
DP[M][mod][use]를 M자리수 일때 N으로 나눈 나머지가 mod이고 1의 사용 여부를 use라고 하자.
그렇게 하면 DP를 돌리고 역추적하여 M자리 자연수를 구할 수 있다.

혹은 bfs를 알고 있다면 bfs로 풀 수 있다.
$(a+b+c) \equiv (a+b)+c \mod{n}$를 이용하여 a%n을 저장해주면서 $a*10, a*10+1$로 bfs를 돌리다가 a가 0이 되면 문자열을 출력하고 종료하면 된다.

---

# 축구
## 요약
90분동안 5분으로 나누어진 경기를 분석하여 a팀이 득점할 확률과 b팀이 득점할 확률 퍼센트 단위로 주어진다.
경기가 끝난 후 적어도 한 팀이 골을 소수로 득점할 확률을 구하는 문제

## 제한
주어지는 확률은 모두 0보다 크거나 같고 100보다 작거나 같은 정수
정답과의 절대/상대 오차가 10-6이내

---

## 풀이

최대 $18$골을 넣을 수 있다.
따라서 넣을 수 있는 소수개수의 골은 $2,3,5,7,11,13,17$이다.

우선 $A$팀이 득점할 확률을 $P_{A}$, $B$팀이 득점할 확률을 $P_{B}$라고 하자

A팀이 소수점수를 득점할 확률은 다음과 같이 구해줄 수 있다.
$\sum_{i} {18 \choose i} * {P_{A}}^{i} * {(1-P_{A})}^{18-i}, \in \set{2,3,5,7,11,13,17}$

여기에서 이항계수 ${n \choose r}$은 DP[n][r] = DP[n-1][r-1] + DP[n-1][r]로 구해줄 수 있다.

---

# 행렬 곱셈 순서

## 요약
행렬 N개의 크기가 주어졌을 때, 모든 행렬을 곱하는데 필요한 곱셈 연산 횟수의 최솟값을 구하는 문제

## 제한
행렬의 개수 N(1 ≤ N ≤ 500)
행렬의 크기 r과 c(1 ≤ r, c ≤ 500)

---

## 풀이
$DP[i][j]$를 $i$번째 행렬 부터 $j$번째 행렬까지의 최소 곱셈 횟수라고 하자
$DP[i][j]=\min(DP[i][k]+DP[k+1][j]+R[i]*C[k]*C[j]), (i\leq k \lt j)$
그러면 i+j=d라고 할때 d=2부터 n까지 돌면서, 즉 대각선 순서대로 보면서 구간을 DP해줄 수 있다.

---

# 헌책방

## 요약
헌책방은 책을 소설, 만화, 잡지등 10개의 장르로 분류한다.
같은 장르의 책을 T권 매입할 때, 책 한 권 당 매입 가격이 기준 가격보다 T-1원 높아진다
책 N권 중 K권을 팔려고 한다.
총 매입 가격의 최댓값을 구하는 문제

# 제한
$2 ≤ N ≤ 2000, 1 ≤ K < N$
가격 $C_i$, 장르 $G_i$ $(1 ≤ Ci ≤ 105, 1 ≤ Gi ≤ 10)$

---

## 풀이
우선 같은 장르의 책을 판매하는 경우 가격이 큰 순서대로 판매하는 것이 이득이므로 가격 내림차순으로 정렬한다.
$PRICE[i][j]$를 장르 i를 j개 팔았을때 얻을수 있는 최대 금액이라고 하고 미리 전처리하자.

$DP[i][j]$를 $1~i$번째 장르에서 j개를 판매 했을때 가격이라고 정의하자.
그러면 아래와 같이 전이할 수 있다.
$DP[i][j] = \max(DP[i-1][j-l] + PRICE[i][l]), 1\leq l\leq $

---

# 248 게임

## 요약
이 게임은 N개의 양수로 시작하여, 인접한 두 개의 같은 수를 1 큰 수로 바꿀 수 있다.
목표는 가능한 모든 합병이 끝났을 때 수열에서 가장 큰 수를 최대화하는 문제

## 제한
$(2 ≤ N ≤ 248)$
$1\leq A_i \leq 40$

---

## 풀이
dp[i][j] = [i, j]구간에서 만들 수 있는 유일한 정수 중 최댓값이라고 하자.

유일한 정수라는 것은 숫자들을 합쳐서 남는 단 한 개의 정수를 의미한다.
만약 한 개의 정수를 남기지 못한다면 0으로 정의한다.

dp[i][k]와 dp[k+1][j]가 같은 경우 dp[i][j] = dp[i][k] + 1이 된다.

---

# NP-hard

## 요약
변형된 외판원 문제(TSP)로, N개의 도시를 한 번씩 방문하며 소요 시간을 최소화
각 도시 간의 거리가 주어지고, K번 도시를 방문할 때는 K보다 작은 도시들을 순서대로 모두 방문해야 한다.
첫 도시와 마지막 도시는 동일할 필요가 없으며, 최종 목표는 최소 소요 시간을 찾는 문제

## 풀이
최적해는 감소하다가 1을 찍고 증가하는 형태
1부터 시작해서 정점을 양끝에 추가하는 형태의 DP를 해주면 된다.
$D[s][e] = min(f(nxt,e)+G[nxt][s], f(s,nxt)+G[e][nxt])$

---

# 산책

## 요약
상근이는 (1,1)에서 (H,W)까지 산책하며 각 교차로에 적힌 '오'(오른쪽)와 '아'(아래)라는 문자에 따라 이동
'오'일 경우 '아'로 바꾸고 오른쪽으로, '아'일 경우 '오'로 바꾸고 아래로 진행
도로의 끝에 도달하면 산책을 종료하며, N번째 산책 경로를 구하는 문제

## 제한
$1 ≤ H,W ≤ 1000, 1 ≤ N ≤ 107$

---

## 풀이
각 교차로에 홀수번 방문하면 적힌대로 짝수번 방문하게 되면 적혀있는것과 반대방향으로 이동하면 된다.
각 교차로에 방문하는 횟수는 DP를 이용하여 구해줄 수 있다.
아래와 비슷하게 현재 DP[i][j]에서 아래와 위로 방문횟수를 전이해주면 된다.
$DP[i+1][j] += DP[i][j]+!A[i][j]>>1$
$DP[i][j+1] += DP[i][j]+A[i][j]>>1$

---

# 가로등 끄기

## 요약
마징가는 가로등을 끄기 위해 5시 정각에 한 가로등 아래에서 출발
가로등의 위치와 소비 전력이 주어질 때, 마징가는 1m/sec의 속도로 이동하며 가로등을 끄는 순서를 정해 전력 낭비를 최소화하여 전력의 최솟값을 구하는 문제

## 제한
가로등의 개수를 나타내는 정수 $N(1 ≤ N ≤ 1,000)$
마징가 처음에 위치하는 가로등 번호 $M \leq N$
가로등의 위치 $D(0 ≤ D ≤ 1,000)$
가로등의 전력소비량 $W(1 ≤ W ≤ 100,000,000)$

낭비되는 전력의 최솟값은 $1,000,000,000$ 보다는 항상 작음이 보장됨

---

## 풀이
http://boj.kr/a877b0eebe9b40fd812101d3002c51f9


---

# 다각형의 분할
## 요약
N각형이 주어졌을 때, 가능한 삼각분할의 경우의 수와 사각분할의 경우의 수를 구하는 문제
회전, 또는 대칭을 이용한 경우에는 같은 것으로 세지 않고 다른 것으로 센다.
1e9으로 나눈 나머지 출력

## 제한
$N(3 ≤ N ≤ 1,000)$

---

## 풀이

단순한 N각형의 삼각분할은 카탈란 수임이 잘 알려져 있다.
하지만 사각분할은 귀찮고 N제한이 1000밖에 안되니 DP로 구해주자.
$dpt[i] += (dpt[j]*dpt[i-j+1]) \mod {1,000,000,000}$
$dps[i] += (dps[j]*dps[k]*dps[i-j-k+2]) \mod {1,000,000,000}$
http://boj.kr/e0a2398c686e4583b344b15f9a93b8e0

0 comments on commit e683da2

Please sign in to comment.