generated from just-the-docs/just-the-docs-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- 백준 17404번 문제 해설
- Loading branch information
Showing
4 changed files
with
164 additions
and
56 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
--- | ||
title: 백준 17404 | RGB거리 2 | ||
level: GOLD IV | ||
layout: default | ||
parent: 문제 풀이 | ||
--- | ||
{% assign title = page.title | split: " | " %} | ||
{% assign name = title[0] %} | ||
{% assign title = title[1] %} | ||
{% assign number = name | split: " " %} | ||
{% assign number = number[1] %} | ||
|
||
# **{{ title }}** | ||
{: .no_toc .fs-9 } | ||
|
||
{{ name }} | ||
{: .fs-4 .d-inline } | ||
|
||
{% if page.level contains 'BRONZE' %} | ||
{{ page.level }} | ||
{: .label .label-bronze } | ||
{% elsif page.level contains 'SILVER' %} | ||
{{ page.level }} | ||
{: .label .label-silver } | ||
{% elsif page.level contains 'GOLD' %} | ||
{{ page.level }} | ||
{: .label .label-gold } | ||
{% elsif page.level contains 'PLATINUM' %} | ||
{{ page.level }} | ||
{: .label .label-platinum } | ||
{% endif %} | ||
|
||
<br/> | ||
|
||
1. TOC | ||
{:toc} | ||
|
||
--- | ||
|
||
## 문제 내용 | ||
{: .fw-700 } | ||
|
||
![problem.png](../assets/screenshots/b{{ number }}.png) | ||
|
||
#### [문제 링크](https://www.acmicpc.net/problem/{{ number }}) | ||
{: .no_toc .fs-4 } | ||
|
||
## 해결 방안 | ||
{: .fw-700 } | ||
|
||
<div class="code-example" markdown="1"> | ||
총 N개의 집에 빨강, 초록, 혹은 파랑 3가지 색 중에 하나의 색을 칠해야한다. | ||
각각의 집은 자신의 앞뒤에 있는 집과 색이 달라야 한다. | ||
예로 들어, 8번째 집은 7번째 집과 9번째 집과의 색이 달라야 한다. | ||
추가적으로, 1번째 집과 맨 마지막 집인 N번째 집은 서로 색이 달라야 한다. | ||
때문에 1번째 집은 2번째와 N번째, N번째 집은 (N-1)번째와 1번째 집과 색이 서로 달라야 한다. | ||
각 집에 빨강이나 초록, 파랑 3가지 색을 칠하는 각각의 비용이 있으며, | ||
문제에서 요구하는 바는 규칙에 따라 N개의 집에 모두 색을 칠했을 때의 드는 비용의 최솟값이다. | ||
{: .mb-1 } | ||
|
||
우선, 각 집은 자신의 이전에 있는 집과 다음에 있는 집의 색이 달라야 하는 조건을 점화식으로 생각해보자. | ||
i번째 집에 (i-1)번째 집과 (i+1)번째 집과 다른 색이 칠해져 있다고 한다면, | ||
(i+1)번째 집을 기준으로 보면 이미 i번째에는 다른 색이 칠해져 있는 것이므로 (i+2)번째 색만 고려하면 된다. | ||
다시 말해, 임의의 집과 그 다음 집에서의 색이 다르다는 것은 그 다음 집에서 이전 집과 색이 다르다는 것과 동치라는 것이다. | ||
때문에 **각 집에 대하여 이전 집과 다른 색을 칠하기만 한다면, 임의의 집은 항상 자신의 앞뒤의 집과 다른 색을 가지는 규칙을 만족한다**. | ||
{: .my-1 } | ||
|
||
그 다음에는 1번째 집과 N번째 집과의 관계만 고려하면 된다. | ||
인접한 집들은 자신의 이전 집과의 관계만 고려하면 되지만, 1번째와 N번째는 각각의 경우의 수를 모두 고려하는 수 밖에 없다. | ||
1번째 집이 빨강일 때에는 N번째 집은 초록이나 파랑이어야 하고, 파랑일 때는 N번째 집은 빨강과 초록이어야 한다. | ||
정리하자면, | ||
**각각 빨강, 파랑, 초록에서 시작한 집의 경우에는 N번째 집이 빨강, 파랑, 초록인 경우 중 시작한 집의 색깔을 제외한 경우의 최솟값을 찾으면 문제의 해답이 된다**. | ||
{: .my-1 } | ||
|
||
이제 문제를 푸는 알고리즘에 대해 알아보자. | ||
먼저, 첫 번째 집을 빨강, 파랑, 초록으로 칠하는 경우를 각각 구분지어야 한다. | ||
두번째 집부터 N번째 집까지는 현재 칠하려는 색과 이전에 칠해진 색을 비교하며, | ||
이전 집에서 현재 칠하려는 색과 다른 두 색을 칠한 경우 중 총 비용이 더 적게 든 쪽을 고른다. | ||
N번째 집까지 이 과정을 반복한 후, 첫 번째 집과 N번째 집의 색이 다른 경우 중 최솟값을 찾으면 된다. | ||
{: .mt-1 } | ||
</div> | ||
|
||
## 풀이 코드 | ||
{: .fw-700 } | ||
|
||
```cpp | ||
#include <iostream> | ||
#include <vector> | ||
#define MAX_VALUE 10000 | ||
|
||
using namespace std; | ||
|
||
int main() { | ||
// Fast IO | ||
cin.tie(0); | ||
cout.tie(0); | ||
ios_base::sync_with_stdio(false); | ||
|
||
int n; // 집의 개수 | ||
long rgb[3]; // 각 집에서의 빨강, 초록, 파랑으로 칠하는 비용 | ||
|
||
// 1번째 집을 빨강으로 칠했을 때의 각 집에서의 빨강, 초록, 파랑으로 칠하는 최소 비용 | ||
vector<int> rStart(3, MAX_VALUE); | ||
// 1번째 집을 초록으로 칠했을 때의 각 집에서의 빨강, 초록, 파랑으로 칠하는 최소 비용 | ||
vector<int> gStart(3, MAX_VALUE); | ||
// 1번째 집을 파랑으로 칠했을 때의 각 집에서의 빨강, 초록, 파랑으로 칠하는 최소 비용 | ||
vector<int> bStart(3, MAX_VALUE); | ||
// 각각의 칠하는 최소 비용은 처음에는 최댓값으로 시작함 | ||
|
||
// 이전 집을 빨강, 초록, 파랑으로 칠했을 경우에 대한 각각의 총 비용 | ||
vector<int> preValue(3); | ||
// 1번째 집을 빨강, 초록, 파랑으로 칠했을 때의 N번째 집에 대한 최소 비용 | ||
int minCost[3]; | ||
|
||
cin >> n; | ||
for(int i = 0; i < n; i++) { | ||
// 각 집을 빨강, 초록, 파랑으로 칠하는 비용 입력 | ||
cin >> rgb[0] >> rgb[1] >> rgb[2]; | ||
|
||
// 맨 처음 입력의 경우에는 각각 1번째 집에 칠하는 색깔의 비용만 고려한다. | ||
if(i == 0) { | ||
rStart[0] = rgb[0]; | ||
gStart[1] = rgb[1]; | ||
bStart[2] = rgb[2]; | ||
} | ||
// 2번째부터는 현재 칠하려는 색깔과 이전 집에서 다른 색을 칠한 경우만 고려하고, | ||
// 그 중 최솟값을 골라 현재 칠하려는 색깔과 합한다. | ||
else { | ||
// 1번째 집이 빨강일 경우에 대한 반복 | ||
preValue = rStart; | ||
rStart[0] = min(preValue[1], preValue[2]) + rgb[0]; | ||
rStart[1] = min(preValue[0], preValue[2]) + rgb[1]; | ||
rStart[2] = min(preValue[0], preValue[1]) + rgb[2]; | ||
// 1번째 집이 초록일 경우에 대한 반복 | ||
preValue = gStart; | ||
gStart[0] = min(preValue[1], preValue[2]) + rgb[0]; | ||
gStart[1] = min(preValue[0], preValue[2]) + rgb[1]; | ||
gStart[2] = min(preValue[0], preValue[1]) + rgb[2]; | ||
// 1번째 집이 파랑일 경우에 대한 반복 | ||
preValue = bStart; | ||
bStart[0] = min(preValue[1], preValue[2]) + rgb[0]; | ||
bStart[1] = min(preValue[0], preValue[2]) + rgb[1]; | ||
bStart[2] = min(preValue[0], preValue[1]) + rgb[2]; | ||
} | ||
} | ||
|
||
// 1번째 집이 빨강인 경우, 마지막 집이 초록이나 파랑인 경우 중 최솟값을 취한다. | ||
minCost[0] = min(rStart[1], rStart[2]); | ||
// 1번째 집이 초록인 경우, 마지막 집이 빨강이나 파랑인 경우 중 최솟값을 취한다. | ||
minCost[1] = min(gStart[0], gStart[2]); | ||
// 1번째 집이 파랑인 경우, 마지막 집이 빨강이나 초록인 경우 중 최솟값을 취한다. | ||
minCost[2] = min(bStart[0], bStart[1]); | ||
|
||
// 1번째 집이 빨강, 초록, 파랑인 3가지 경우 중 최솟값을 찾는다. | ||
minCost[0] = min(minCost[0], minCost[1]); | ||
minCost[0] = min(minCost[0], minCost[2]); | ||
|
||
cout << minCost[0] << endl; | ||
return 0; | ||
} | ||
``` | ||
{: .lh-0 .fw-700 .fs-4 } |