본문 바로가기
알고리즘/백준

알고리즘(C++) / 백준 12845 : 모두의 마블

by clean_h 2021. 3. 7.
728x90

12845

www.acmicpc.net/problem/12845

 

12845번: 모두의 마블

영관이는 게임을 좋아한다. 별의별 게임을 다 하지만 그 중에서 제일 좋아하는 게임은 모두의 마블이다. 어김없이 오늘도 영관이는 학교 가는 버스에서 캐릭터 합성 이벤트를 참여했다. 이번 이

www.acmicpc.net

 

문제

영관이는 게임을 좋아한다. 별의별 게임을 다 하지만 그 중에서 제일 좋아하는 게임은 모두의 마블이다. 어김없이 오늘도 영관이는 학교 가는 버스에서 캐릭터 합성 이벤트를 참여했다.

이번 이벤트는 다음과 같다. 순서가 매겨진 여러 장의 카드가 있다. 각각의 카드는 저마다 레벨이 있다.

카드 A에 카드 B를 덧붙일 수 있다. 이때 붙이는 조건은 다음과 같다.

  1. 두 카드는 인접한 카드여야 한다.
  2. 업그레이드 된 카드 A의 레벨은 변하지 않는다.

카드 합성을 할 때마다 두 카드 레벨의 합만큼 골드를 받는다.

영관이가 골드를 최대한 많이 받을 수 있게 여러분이 도와주자.

예를 들어, c1, c2, c3로 연속된 카드 3개가 있고 각각 레벨이 40,30,30 이라고 하자.

이 카드들을 합치는 과정에서, 먼저 c3에 c2를 합쳐 임시 카드 x1을 만든다. x1의 레벨은 30이고 획득 골드는 60이다. 그 다음엔 c1에 x1을 합쳐 카드 x2를 만들면 레벨이 40이고 70만큼의 골드를 획득할 수 있다. 이때, 영관이가 획득한 골드는 70+60 = 130이다.

다른 방법으로 c1에 c2를 덧붙인 카드 x1을 만들면, x1의 레벨은 40이고 획득한 골드는 70이다.

x1에 c3를 덧붙인 카드 x2의 레벨은 40이고 획득 골드는 70이다. 이때, 영관이가 획득한 골드는 70 + 70 = 140이다. 이외에 더 많은 골드를 받는 방법이 없으므로 140이 획득할 수 있는 최대 골드이다.

 

입력

카드의 개수 n(0 < n ≤ 1,000)이 주어진다.

다음 줄에 각각 카드의 레벨 Li가 순서대로 주어진다. (0 < Li ≤ 100,000)

 

출력

영관이가 받을 수 있는 골드의 최댓값을 출력한다.

 

코드

//12845 모두의 마블
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
	int n;
	vector <int> L;

	cin >> n;

	int num;
	for (int i = 0; i < n; i++) {
		cin >> num;
		L.push_back(num);
	}

	sort(L.begin(), L.end(), greater<>());
	
	int gold = 0;
	int max_level = L[0];
	for (int i = 1; i < L.size(); i++) {
		gold += max_level + L[i];
	}
	cout << gold << endl;

	return 0;
}

 

설명

vector로 선언한 L에 카드의 레벨을 차례대로 저장한다.

sort함수로 L을 큰 수부터 내림차순으로 정렬한다. 가장 큰 레벨을 찾기 위해서이다.

gold 변수에 골드의 값을 저장한다.

max_level은 입력받은 레벨 중 가장 큰 레벨을 저장한다.

 

* 문제의 핵심은 가장 큰 레벨과 합성하는 것이다.

 

가장 큰 레벨과 합성해야 획득한 골드가 최대값이 된다. 

예를 들어 40 50 40 70 30 입력받았다고 할 때 70+40, 70+30, 70+50, 70+40 순서대로 합성되어야 최대가 된다. 

 

출력

 

고찰

이번 문제는 조금만 생각하면 풀 수 있는 문제였다.

처음에는 문제를 한 번 읽었을 때는 이해가 한번에 되는 문제는 아니었다. 여러 번 읽어보고 예시를 보면서 문제를 이해할 수 있었다.

입력 예시를 직접만들어보고 결과가 어떻게 나와야 할지 확인하고 구현할 수 있었다. 

 

난이도

●◐

728x90

댓글