https://www.acmicpc.net/problem/3687

 

3687번: 성냥개비

각 테스트 케이스에 대해서 입력으로 주어진 성냥개비를 모두 사용해서 만들 수 있는 가장 작은 수와 가장 큰 수를 출력한다. 두 숫자는 모두 양수이어야 하고, 숫자는 0으로 시작할 수 없다. 

www.acmicpc.net

1. 풀이방법

- 최대값은 쉽습니다. 자릿수를 크게 하는 것이 가장 큰 값을 만드는 것입니다.

 

- 같은 성냥을 사용할 떄, 가장 작은 수를 쓰면 됩니다. 쉬우므로 생략하겠습니다.

 

- 최솟값이 어렵습니다.

 

- dp로 좀 더 쉽게 접근했고 오랜만에 dp하려니까 머리가 너무 안돌아갔습니다 ㅠㅠ

 

- makenum배열에 성냥으로 만드는 수를 넣어놓고, 바텀업으로 아래의 점화식과 같습니다.

 

- for (int i = 9; i < 101; i++) {
           dp[i] = dp[i - 2] * 10 + makenum[2]; //init 설정

               for (int j = 3; j < 8; j++) {
                    dp[i] = min(dp[i], dp[i - j] * 10 + makenum[j]);
                }
    }

 

 

2. 주의사항

- 0으로 시작하면 안된다.

 

- 그러므로 dp[6]은 6으로 초기화 하고 makenum[6]에는 0을 넣습니다.

 

- 즉 makenum[6]은 6 성냥으로 만들 수 있는 수 인데, 이후 점화식에서는 6개의 성냥으로는 0을 만들어 쓰겠다입니다

 

 

3. 나의코드

#include<iostream>
#include<string>
#include<queue>
#include<algorithm>
#include<vector>
using namespace std;

int T, n;
int makenum[9] = { 0, 0, 1, 7, 4, 2, 0, 8, 10 }; //일단 6은 0을 넣어놓자 (초기 값 셋팅 이후에는 6개 성냥으로는 0을 만들어야함)
long long dp[101];

void getmin() {
	for (int i = 1; i < 9; i++) {
		dp[i] = makenum[i]; // 성냥 i 개를 가지고 만들 수 있는 min값
	}
	dp[6] = 6; //0으로 시작하는 것을 방지하기 위해

	for (int i = 9; i < 101; i++) {
		dp[i] = dp[i - 2] * 10 + makenum[2]; //init 설정

		for (int j = 3; j < 8; j++) {
			dp[i] = min(dp[i], dp[i - j] * 10 + makenum[j]);
		}
	}
}
int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	int T,n;
	cin >> T;
	getmin();
	while (T--) {
		cin >> n;
		cout << dp[n];
		cout << " ";
		//가장 큰수
		if (n % 2 == 1) { //홀수
			cout << 7; n -= 3;
		}
		while (n != 0) {
			cout << 1; n -= 2;
		}
		cout << "\n";
	}
	return 0;
}

'알고리즘 문제풀이 > 다이나믹 프로그래밍' 카테고리의 다른 글

백준 1932 [C++]  (0) 2021.08.10
백준 1103 [C++]  (0) 2021.07.06
백준 1793 [C++]  (0) 2021.02.04
백준 1965 [C++]  (0) 2021.02.03
백준 1463 [C++] - 메모리초과  (0) 2020.12.15

+ Recent posts