일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- es6
- form
- django ORM
- DRF
- 장고
- 알고리즘 풀이
- 백준
- 알고리즘
- react
- js
- c++
- 알고리즘 문제
- HTML
- 파이썬
- Django
- django widget
- PYTHON
- javascript
- API
- CSS
- 알고리즘 연습
- web
- AWS
- django rest framework
- MAC
- Algorithm
- java
- 파이썬 알고리즘
- Baekjoon
- Git
Archives
- Today
- Total
수학과의 좌충우돌 프로그래밍
[C++] BAEKJOON 8895번 막대배치(ACM-ICPC Daejeon 2012) 본문
동적계획법을 사용한 문제였습니다. 먼저 점화식을 세워보도록 하겠습니다.
dp[n][l][r]
를 n 개의 막대에 대해, 왼쪽에서 보이는 막대가 l 개, 오른쪽에서 보이는 막대가 r 개인 경우의 개수 라고 정의하겠습니다. 그리고 이를 하위 문제로 나누기 위해서 l 과 r 값에 영향을 많이 주는 길이 n 막대가 아닌 길이 1 막대로 생각을 해보겠습니다.
-
길이 1 막대가 가장 왼쪽에 위치한 경우
이 막대가 영향을 줄 수 있는 건 n 과 l 입니다. 이 막대가 사라진다면 n과 l 만 1 감소하게 되죠. 따라서 다음과 같이 표현 할 수 있습니다.
dp[n-1][l-1][r]
-
길이 1 막대가 가장 오른쪽에 위치한 경우
위와 유사하게 n 과 r 에만 영향을 미치고, 다음과 같이 표현됩니다.
dp[n-1][l][r-1]
-
길이 1 막대가 2~n-1 에 위치한 경우
길이 1인 막대가 2~n-1 에 위치한다면 사라지더라도 l 과 r 값에 영향을 주지 않습니다. 따라서 n 만 1 줄어들겠죠.
dp[n-1][l][r-1]
이 때 1,2 번째 case 는 1가지 경우, 3번째 case는 n-2 가지 경우가 있으므로, 다음과 같은 점화식을 얻을 수 있습니다.
dp[n][l][r] = dp[n-1][l-1][r] + dp[n-1][l][r-1] + (n-2) * dp[n-1][l][r]
전체 풀이
이 점화식만 구했다면 문제 푸는 건 어렵지 않습니다.
#include <iostream>
using namespace std;
long long dp[21][21][21];
int main(int argc, const char * argv[]) {
dp[1][1][1] = 1;
for (int n=2;n<=20;n++){
for (int l=1;l<=20;l++){
for (int r=1;r<=20;r++){
dp[n][l][r] = dp[n-1][l-1][r] + dp[n-1][l][r-1] + (n-2)*dp[n-1][l][r];
}
}
}
int T;
cin >> T;
for (int t=0;t<T;t++){
int n,l,r;
cin >> n >> l >> r;
cout << dp[n][l][r] << endl;
}
return 0;
}
'알고리즘 > C++' 카테고리의 다른 글
[C++] BAEKJOON 5052번 전화번호목록 (0) | 2019.08.26 |
---|---|
[C++] BAEKJOON 8901번 화학제품(ACM-ICPC Daejeon 2011) (0) | 2019.08.02 |
[C++] BAEKJOON 9455번 박스(ACM-ICPC Daejeon 2013) (0) | 2019.07.26 |
[C++] 이진 탐색 알고리즘 (1) | 2019.03.26 |
[C++] 최적의 소수찾기, 에라토스테네스의 체 (1) | 2019.02.08 |
Comments