hyelie
hyelie
Hyeil Jeong
       
글쓰기    관리    수식입력
  • 전체보기 (495)
    • PS (283)
      • Algorithm (28)
      • PS Log (244)
      • Contest (6)
      • Tips (5)
    • Development (52)
      • Java (14)
      • Spring (23)
      • SQL (2)
      • Node.js (2)
      • Socket.io (3)
      • Study (4)
      • Utils (4)
    • DevOps (36)
      • Git (5)
      • Docker (4)
      • Kubernetes (2)
      • GCP (3)
      • Environment Set Up (8)
      • Tutorial (12)
      • Figma (2)
    • CS (74)
      • OOP (7)
      • OS (24)
      • DB (2)
      • Network (24)
      • Architecture (0)
      • Security (2)
      • Software Design (0)
      • Parallel Computing (15)
    • Project (15)
      • Project N2T (5)
      • Project ASG (0)
      • Project Meerkat (1)
      • Model Checking (7)
      • Ideas (2)
    • 내가 하고싶은 것! (34)
      • Plan (16)
      • Software Maestro (10)
      • 취준 (8)
hELLO · Designed By 정상우.
hyelie

hyelie

PS/Algorithm

2020/07/06 공부 - dynamic programming

 backtrack을 끝내고 이제 DP를 해볼 차례다.

 DP는 원래 n square의 시간복잡도가 걸리는 일을 2가지 방법을 이용해 n에 linear하게 수행할 수 있도록 해주는 기법 중 하나이다. 이 2가지 방법은
 첫째, 현재의 state로 미래의 state를 계산해 주는 점화식
 둘째, 이미 계산했던 값이라면 계산했던 값을 사용하는 memoization
 두 가지를 사용한다.

 대표적으로 DP를 사용해서 시간을 줄일 수 있는 것이 조합이다. nCr에서 파스칼의 삼각형 특징을 이용해서 복잡한 계산을 조금 간단하게 줄일 수 있는데, 순열 점화식 

$_nC_0=_nC_n=1$
$_nC_r=_{n-1}C_{r-1}+_{n-1}C_r$
에서 2번째 점화식의 우항 부분이 계산되어 있다면 이를 저장해둔 후, 필요할 때 불러오는 방식을 사용한다.

 예제로 백준 2579번을 풀었다.

int dynamic_programming(vector<int>& point_per_stair, int N) {
	// memoization
	vector<int> dp(N);

	// 점화식의 초항
	dp[0] = point_per_stair[0];
	dp[1] = point_per_stair[0] + point_per_stair[1];
	dp[2] = point_per_stair[2] + max(point_per_stair[0], point_per_stair[1]);

	// 어떤 i번째 계단
	// i번째 계단을 계산하기 위해서는 i-1번째, i-2번째, i-3번째 계단까지 최댓값이 필요함.
	// 가능한 경우의 수; i, i-1, i-2는 존재하지 않음.
	// i번째 밟고 i-1번째 밟고 i-3번째 밟은 경우 (i-2번째 계단을 밟지 않아서)
	// i번째 밟고 i-2번째 밟은 경우

	for (int i = 3; i < N; i++) {
		dp[i] = max(dp[i - 3] + point_per_stair[i - 1] + point_per_stair[i], dp[i - 2] + point_per_stair[i]);
		// dp[i] = i번째 계단을 최종 계단으로 생각했을 때, 최대 점수
		// dp[i-3] = i-3번째 계단 밟았을 때 최고 점수
		// + point[i-1] + point[i] = i-3번째, i-1번째, i번째 계단 밟았을 때 점수
		// dp[i-2] = i-2번째 계단 밟았을 때 최고 점수
		// + point[i] = i-2번째 계단 밟고 i번째 계단 밟았을 때 점수
	}

	return dp[N-1];
}

 

 구현한 이유는 코드에 기술되어 있다. dp[i]는 i번째 계단을 최종 계단으로 생각했을 때, 그러니까 i번째 계단을 밟았을 때 최대 점수이다. 이 dp vector를 이용해서 점화식을 세울 수 있다. dp[i]의 특징을 이용하기 때문에 점화식이 한 줄로 나오게 된다.

 

void solve() {
	int N;
	cin >> N;
	vector<int> point_per_stair(N);
	for (int i = 0; i < N; i++) {
		cin >> point_per_stair[i];
	}

	cout << dynamic_programming(point_per_stair, N);
}

'PS > Algorithm' 카테고리의 다른 글

2020/07/08 공부 - dynamic programming  (0) 2022.06.21
2020/07/07 공부 - dynamic programming  (0) 2022.06.21
2020/07/06 공부 - backtracking  (0) 2022.06.21
2020/07/04 공부 - backtracking  (0) 2022.06.21
2020/07/02 공부 - backtracking  (0) 2022.06.21
    hyelie
    hyelie

    티스토리툴바