728x90

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

 

9325번: 얼마?

문제 해빈이는 학교를 다니면서 틈틈히 번 돈으로 자동차를 사려고 한다. 자동차에 여러 가지 옵션을 포함시킬 수 있는데 해빈이는 덧셈과 곱셈을 하지 못하기 때문에 친구 태완이에게 도움을 청했다. 하지만 태완이도 덧셈과 곱셈을 못한다. 불쌍한 이 두 친구를 위해 모든 옵션이 주어진 자동차를 구매하는데 필요한 액수를 계산해 주자. 입력 첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스의 첫 줄엔 자동차의 가격 s가 주어진다. (1 ≤ s ≤ 100

www.acmicpc.net

#include <iostream>
using namespace std;

int main() {
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);
	int testCase;
	cin >> testCase;
	for (int t = 0; t < testCase; t++) {
		int total = 0;
		int price;
		cin >> price;
		total += price;
		int n;
		cin >> n;
		for (int i = 0; i < n; i++) {
			int num, cost;
			cin >> num >> cost;
			total += (num * cost);
		}
		cout << total << '\n';
	}
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 1074번 Z  (0) 2020.03.23
[백준] 11066번 파일 합치기  (0) 2020.03.20
[백준] 4539번 반올림  (0) 2020.03.20
[백준] 1965번 상자넣기  (0) 2020.03.17
[백준] 4597번 패리티  (0) 2020.03.17
728x90

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

 

4539번: 반올림

문제 정수 x가 주어졌을 때, 10보다 크다면, 1의 자리에서 반올림하고, 결과가 100보다 크면, 10의 자리에서 반올림하고, 1000보다 크면, 100의 자리에서 반올림하고... 이와 같이 계속 반올림하는 프로그램을 작성하시오. 입력 첫째 줄에 테스트 케이스의 개수 n이 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있으며, 정수 x가 주어진다. (0 ≤ x ≤ 99999999) 출력 각 테스트 케이스마다 입력으로 주어지는 정수를 문제 설명에 나온

www.acmicpc.net

#include <iostream>
#include <vector>
using namespace std;

int main() {
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);
	int n;
	cin >> n;
	for (int i = 0; i < n; i++) {
		int a;
		cin >> a;
		if (a > 10) {
			a = (a + 5) / 10 * 10;
		}
		if (a > 100) {
			a = (a + 50) / 100 * 100;
		}
		if (a > 1000) {
			a = (a + 500) / 1000 * 1000;
		}
		if (a > 10000) {
			a = (a + 5000) / 10000 * 10000;
		}
		if (a > 100000) {
			a = (a + 50000) / 100000 * 100000;
		}

		if (a > 1000000) {
			a = (a + 500000) / 1000000 * 1000000;
		}
		if (a > 10000000) {
			a = (a + 5000000) / 10000000 * 10000000;
		}
		cout << a << '\n';
	}
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 11066번 파일 합치기  (0) 2020.03.20
[백준] 9325번 얼마?  (0) 2020.03.20
[백준] 1965번 상자넣기  (0) 2020.03.17
[백준] 4597번 패리티  (0) 2020.03.17
[백준] 1309번 동물원  (0) 2020.03.17
728x90

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

 

1965번: 상자넣기

정육면체 모양의 상자가 일렬로 늘어서 있다. 상자마다 크기가 주어져 있는데, 앞에 있는 상자의 크기가 뒤에 있는 상자의 크기보다 작으면, 앞에 있는 상자를 뒤에 있는 상자 안에 넣을 수가 있다. 예를 들어 앞에서부터 순서대로 크기가 (1, 5, 2, 3, 7)인 5개의 상자가 있다면, 크기 1인 상자를 크기 5인 상자에 넣고, 다시 이 상자를 크기 7인 상자 안에 넣을 수 있다. 하지만 이렇게 상자를 넣을 수 있는 방법은 여러 가지가 있을 수 있다. 앞의

www.acmicpc.net

그냥 LIS(Longest Increasing Sequence)를 구하면 된다.

#include <iostream>
#include <vector>
using namespace std;

int main() {
	int n;
	cin >> n;
	vector<int> boxes(n);
	for (int i = 0; i < n; i++) {
		cin >> boxes[i];
	}
	int maxBox = 0;
	vector<int> dp(n);
	dp[0] = 1;
	for (int i = 1; i < n; i++) {
		int maxDp = 0;
		for (int j = 0; j < i; j++) {
			if (dp[j] > maxDp && boxes[j] < boxes[i]) {
				maxDp = dp[j];
			}
		}
		dp[i] = maxDp + 1;
		if (dp[i] > maxBox)
			maxBox = dp[i];
	}
	cout << maxBox;
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 9325번 얼마?  (0) 2020.03.20
[백준] 4539번 반올림  (0) 2020.03.20
[백준] 4597번 패리티  (0) 2020.03.17
[백준] 1309번 동물원  (0) 2020.03.17
[백준] 2225 합분해  (0) 2020.03.16
728x90

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

 

4597번: 패리티

문제 1의 개수가 홀수개인 비트스트링을 "홀수 패리티"를 가지고 있다고 한다. 또, 짝수개인 경우에는 "짝수 패리티"를 가지고 있다고 한다. 또, 0도 짝수로 간주한다. 따라서, 1이 없는 비트 스트링은 짝수 패리티를 가지고 있다. 마지막 숫자가 지워진 비트 스트링이 주어지고, 이 비트 스트링의 패리티가 주어졌을 때, 마지막 숫자를 올바르게 구하는 프로그램을 작성하시오. 입력 입력은 여러 개의 비트 스트링으로 이루어져 있다. 각 비트 스트링은 한 줄로 이

www.acmicpc.net

#include <iostream>
#include <string>
using namespace std;

int main() {
	while (true) {
		string s;
		cin >> s;
		if (s == "#") {
			break;
		}
		int count = 0;
		for (int i = 0; i < s.size() - 1; i++) {
			if (s[i] == '1')
				count++;
		}
		if (s[s.size() - 1] == 'e') {
			if (count % 2 == 0) {
				s[s.size() - 1] = '0';
			}
			else {
				s[s.size() - 1] = '1';
			}
		}
		else {
			if (count % 2 == 0) {
				s[s.size() - 1] = '1';
			}
			else {
				s[s.size() - 1] = '0';
			}
		}
		cout << s << '\n';
	}
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 4539번 반올림  (0) 2020.03.20
[백준] 1965번 상자넣기  (0) 2020.03.17
[백준] 1309번 동물원  (0) 2020.03.17
[백준] 2225 합분해  (0) 2020.03.16
[백준] 2096번 내려가기  (0) 2020.03.15
728x90

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

 

1309번: 동물원

첫째 줄에 우리의 크기 N(1≤N≤100,000)이 주어진다.

www.acmicpc.net

동적계획법 문제이다. 동적계획법 문제는 점화식만 잘 세우면 된다.

나는 일단 4까지는 노가다로 구한 뒤 규칙을 찾았다.

점화식은

dp[i] = 2 * dp[i - 1] + dp[i - 2]

0 1 2 3 4 5 6 7 8 9 10
1 3 7 17 41 99 239 577 1393 3363 8119
#include <iostream>
#include <vector>
using namespace std;

int main() {
	int n;
	cin >> n;
	vector<int> dp(n + 1);
	dp[0] = 1;
	dp[1] = 3;
	for (int i = 2; i <= n; i++) {
		dp[i] = (dp[i - 1] * 2 + dp[i - 2]) % 9901;
	}
	cout << dp[n];
	return 0;
}

 

728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 1965번 상자넣기  (0) 2020.03.17
[백준] 4597번 패리티  (0) 2020.03.17
[백준] 2225 합분해  (0) 2020.03.16
[백준] 2096번 내려가기  (0) 2020.03.15
[백준] 2631번 줄세우기  (0) 2020.03.15
728x90

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

 

2225번: 합분해

첫째 줄에 답을 1,000,000,000으로 나눈 나머지를 출력한다.

www.acmicpc.net

동적계획법으로 풀 수 있다.

아래 표 dp의 k행 n열은 숫자 k개를 가지고 n을 만들 수 있는 경우의 수이다.

3행 4열을 예로 들면

dp[3][4]는 3가지 수4를 만들 수 있는 방법의 개수인데 4는 0+4, 1+3, 2+2, 3+1, 4+0으로 나타낼 수 있다.

그런데 3행을 채울 당시에는 2행까지만 채워있으니 2행까지 구해놓은 것들을 가지고 3행을 구하면 된다.

 

0+4는 dp[1][0]*dp[2][4]로 표현 가능하고

(dp[1][0]은 1가지 수0을 만들 수 있는 방법의 개수, dp[2][4]는 2가지 수4를 만들 수 있는 방법의 개수)

 

1+3은 dp[1][1]*dp[2][3]으로 표현 가능하고

(dp[1][1]은 1가지 수1을 만들 수 있는 방법의 개수, dp[2][3]은 2가지 수3을 만들 수 있는 방법의 개수)

 

2+2는 dp[1][2]*dp[2][2]로 표현 가능하고

(dp[1][2]는 1가지 수2를 만들 수 있는 방법의 개수, dp[2][2]는 2가지 수2를 만들 수 있는 방법의 개수)

 

3+1은 dp[1][3]*dp[2][1]으로 표현 가능하고

(dp[1][3]은 1가지 수3을 만들 수 있는 방법의 개수, dp[2][1]는 2가지 수1을 만들 수 있는 방법의 개수)

 

4+0은 dp[1][4]*dp[2][0]으로 표현 가능하다.

(dp[1][4]는 1가지 수4를 만들 수 있는 방법의 개수, dp[2][0]는 2가지 수0를 만들 수 있는 방법의 개수)

 

즉, dp[3][4] = dp[1][0]*dp[2][4] + dp[1][1]*dp[2][3] + dp[1][2]*dp[2][2] + dp[1][3]*dp[2][1] + dp[1][4]*dp[2][0] 이다.

그런데 1행 즉 K가 1일 때에는 항상 값이 1이므로 1행의 1은 굳이 안 곱해줘도 된다.

따라서  dp[3][4] = dp[2][4] + dp[2][3] + dp[2][2] + dp[2][1] + dp[2][0] 이다.

 

점화식은 dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1] + dp[i - 1][j - 2] + dp[i - 1][j - 3] + ... + dp[i - 1][0] 으로 표현할 수 있다.

#include <iostream>
#include <vector>
using namespace std;

int main() {
	int n, k;
	cin >> n >> k;
	vector<vector<int>> dp(k + 1, vector<int>(n + 1));
	for (int i = 0; i <= n; i++) {
		dp[1][i] = 1;
	}
	for (int i = 2; i <= k; i++) {
		dp[i][0] = 1;
	}
	for (int i = 2; i <= k; i++) {
		for (int j = 1; j <= n; j++) {
			for (int c = 0; c <= j; c++) {
				dp[i][j] = (dp[i][j] + dp[i - 1][c]) % 1000000000;
			}
		}
	}
	cout << dp[k][n];
	return 0;
}

오버플로우가 나지 않게 중간중간 1000000000으로 나눠줘야 한다.

이 코드를 제출하니 12ms가 나왔다.

 

다음은 개선된 코드이다.

#include <iostream>
#include <vector>
#include <iomanip>
using namespace std;

int main() {
	int n, k;
	cin >> n >> k;
	vector<int> dp(n + 1, 1);
	for (int i = 2; i <= k; i++) {
		for (int j = 1; j <= n; j++) {
				dp[j] = (dp[j - 1] + dp[j]) % 1000000000;
		}
	}
	cout << dp[n];
	return 0;
}

이렇게 일차원 배열로도 풀 수 있다.

여기에서 쓰는 점화식은 더 간단하다.

dp[i][j] = dp[i - 1][j] + dp[i][j - 1]이다. 그런데 이것을 일차원 배열로 바꾼 코드이다.

이 방법으로 제출하니 0ms가 걸렸다.

728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 4597번 패리티  (0) 2020.03.17
[백준] 1309번 동물원  (0) 2020.03.17
[백준] 2096번 내려가기  (0) 2020.03.15
[백준] 2631번 줄세우기  (0) 2020.03.15
[백준] 9084번 동전  (0) 2020.03.14
728x90

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

 

2096번: 내려가기

첫째 줄에 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 N개의 줄에는 숫자가 세 개씩 주어진다. 숫자는 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 중의 하나가 된다.

www.acmicpc.net

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

int main() {
	int n;
	cin >> n;
	vector<int> v(3);
	vector<int> minDp(3);
	vector<int> maxDp(3);
	for (int i = 0; i < 3; i++) {
		cin >> v[i];
		minDp[i] = v[i];
		maxDp[i] = v[i];
	}
	
	for (int i = 1; i < n; i++) {
		cin >> v[0] >> v[1] >> v[2];
		int a1 = minDp[0];
		int b1 = minDp[1];
		int c1 = minDp[2];
		int a2 = maxDp[0];
		int b2 = maxDp[1];
		int c2 = maxDp[2];
		minDp[0] = (min(a1 + v[0], b1 + v[0]));
		minDp[1] = (min(min(a1 + v[1], b1 + v[1]), c1 + v[1]));
		minDp[2] = (min(b1 + v[2], c1 + v[2]));
		maxDp[0] = (max(a2 + v[0], b2 + v[0]));
		maxDp[1] = (max(max(a2 + v[1], b2 + v[1]), c2 + v[1]));
		maxDp[2] = (max(b2 + v[2], c2 + v[2]));
	}
	
	int minSum = min(min(minDp[0], minDp[1]), minDp[2]);
	int maxSum = max(max(maxDp[0], maxDp[1]), maxDp[2]);
	cout << maxSum << " " << minSum;
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 1309번 동물원  (0) 2020.03.17
[백준] 2225 합분해  (0) 2020.03.16
[백준] 2631번 줄세우기  (0) 2020.03.15
[백준] 9084번 동전  (0) 2020.03.14
[백준] 1937번 욕심쟁이 판다  (0) 2020.03.14
728x90

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

 

2631번: 줄세우기

KOI 어린이집에는 N명의 아이들이 있다. 오늘은 소풍을 가는 날이다. 선생님은 1번부터 N번까지 번호가 적혀있는 번호표를 아이들의 가슴에 붙여주었다. 선생님은 아이들을 효과적으로 보호하기 위해 목적지까지 번호순서대로 일렬로 서서 걸어가도록 하였다. 이동 도중에 보니 아이들의 번호순서가 바뀌었다. 그래서 선생님은 다시 번호 순서대로 줄을 세우기 위해서 아이들의 위치를 옮기려고 한다. 그리고 아이들이 혼란스러워하지 않도록 하기 위해 위치를 옮기는 아이들의

www.acmicpc.net

LIS(Longest Increasing Sequence)를 구하고 N에서 LIS를 빼주면 된다.

#include <iostream>
#include <vector>
using namespace std;

int main() {
	cin.tie(NULL);
	int n;
	cin >> n;
	vector<int> v(n);
	for (int i = 0; i < n; i++) {
		cin >> v[i];
	}
	vector<int> dp(n);
	dp[0] = 1;
	int lis = 0;
	for (int i = 1; i < n; i++) {
		int maxDp = 0;
		for (int j = 0; j < i; j++) {
			if (dp[j] > maxDp && v[j] < v[i]) {
				maxDp = dp[j];
			}
		}
		dp[i] = maxDp + 1;
		if (dp[i] > lis)
			lis = dp[i];
	}
	cout << n - lis;
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 2225 합분해  (0) 2020.03.16
[백준] 2096번 내려가기  (0) 2020.03.15
[백준] 9084번 동전  (0) 2020.03.14
[백준] 1937번 욕심쟁이 판다  (0) 2020.03.14
[백준] 3036번 링  (0) 2020.03.13
728x90

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

 

9084번: 동전

우리나라 화폐단위, 특히 동전에는 1원, 5원, 10원, 50원, 100원, 500원이 있다. 이 동전들로는 정수의 금액을 만들 수 있으며 그 방법도 여러 가지가 있을 수 있다. 예를 들어, 30원을 만들기 위해서는 1원짜리 30개 또는 10원짜리 2개와 5원짜리 2개 등의 방법이 가능하다. 동전의 종류가 주어질 때에 주어진 금액을 만드는 모든 방법을 세는 프로그램을 작성하시오.

www.acmicpc.net

#include <iostream>
#include <vector>
using namespace std;

int main() {
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);
	int testCase;
	cin >> testCase;
	for (int t = 0; t < testCase; t++) {
		int n, cost;
		cin >> n;
		vector<int> coin(n);
		for (int i = 0; i < n; i++) {
			cin >> coin[i];
		}
		cin >> cost;
		vector<vector<int>> dp(n, vector<int>(cost + 1));
		for (int i = 0; i <= cost; i++) {
			if (i % coin[0] == 0)
				dp[0][i] = 1;
		}
		for (int i = 1; i < n; i++) {
			for (int j = 0; j <= cost; j++) {
				for (int c = 0; c <= j; c += coin[i]) {
						dp[i][j] += dp[i - 1][j - c];	
				}
			}
		}
		cout << dp[n - 1][cost] << '\n';
	}
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 2096번 내려가기  (0) 2020.03.15
[백준] 2631번 줄세우기  (0) 2020.03.15
[백준] 1937번 욕심쟁이 판다  (0) 2020.03.14
[백준] 3036번 링  (0) 2020.03.13
[백준] 5338번 마이크로소프트 로고  (0) 2020.03.13
728x90

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

 

1937번: 욕심쟁이 판다

n*n의 크기의 대나무 숲이 있다. 욕심쟁이 판다는 어떤 지역에서 대나무를 먹기 시작한다. 그리고 그 곳의 대나무를 다 먹어 치우면 상, 하, 좌, 우 중 한 곳으로 이동을 한다. 그리고 또 그곳에서 대나무를 먹는다. 그런데 단 조건이 있다. 이 판다는 매우 욕심이 많아서 대나무를 먹고 자리를 옮기면 그 옮긴 지역에 그 전 지역보다 대나무가 많이 있어야 한다. 만약에 그런 지점이 없으면 이 판다는 불만을 가지고 단식 투쟁을 하다가 죽게 된다(-_-) 이

www.acmicpc.net

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

vector<vector<int>> v;
vector<vector<int>> dp;
int n;

int dfs(int i, int j) {
	bool flag = false;
	if (dp[i][j] != 0) return dp[i][j];
	int maximum = 0;
	if (i + 1 < n && v[i][j] < v[i + 1][j]) {
		int temp = 1 + dfs(i + 1, j);
		if (temp > maximum) {
			dp[i][j] = temp;
			maximum = temp;
		}
		flag = true;
	}
	if (i - 1 >= 0 && v[i][j] < v[i - 1][j]) {
		int temp = 1 + dfs(i - 1, j);
		if (temp > maximum) {
			dp[i][j] = temp;
			maximum = temp;
		}
		flag = true;
	}
	if (j + 1 < n && v[i][j] < v[i][j + 1]) {
		int temp = 1 + dfs(i, j + 1);
		if (temp > maximum) {
			dp[i][j] = temp;
			maximum = temp;
		}
		flag = true;
	}
	if (j - 1 >= 0 && v[i][j] < v[i][j - 1]) {
		int temp = 1 + dfs(i, j - 1);
		if (temp > maximum) {
			dp[i][j] = temp;
			maximum = temp;
		}
		flag = true;
	}
	if (!flag) {
		dp[i][j] = 1;
	}
	return dp[i][j];
}

int main() {
	cin >> n;
	v = vector<vector<int>>(n, vector<int>(n));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> v[i][j];
		}
	}
	int maxDp = 0;
	dp = vector<vector<int>>(n, vector<int>(n));
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			dfs(i, j);
		}
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			if (dp[i][j] > maxDp) maxDp = dp[i][j];
		}
	}
	cout << maxDp;
	return 0;
}
728x90

'알고리즘 문제' 카테고리의 다른 글

[백준] 2631번 줄세우기  (0) 2020.03.15
[백준] 9084번 동전  (0) 2020.03.14
[백준] 3036번 링  (0) 2020.03.13
[백준] 5338번 마이크로소프트 로고  (0) 2020.03.13
[백준] 1699번 제곱수의 합  (0) 2020.03.13

+ Recent posts