Posts 11066 파일합치기
Post
Cancel

11066 파일합치기

11066 파일합치기

알고리즘(DP)

1
2
3
4
5
6
1. 긴 한 줄의 파일들을 두조각으로 분리해서 찾는 방식으로 DP를 함
2. 먼저 0, k-1를 넣음
3. (0, k-1)의 파일 크기의 합을 구한 후, (0,0)-(1,k-1), (0, 1)-(2,k-1) ... 로 모든 두 조각을 만든 후, 그 조각의 비용을 구함
 -> start == end 일 경우 합치지 않으므로 비용은 0
 ex) (0,1) 일 경우, 0 + 0 + file[0] + file[1]
4. 각 조각의 비용은 dp[start][end]에 저장함.

주의점

1
이전 tc의 결과가 dp를 오염시킬 수 있으므로, dp배열은 항상 초기화한다.

코드

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <cstring>
#define MAX_FILE 501

using namespace std;

int k, file[MAX_FILE], DP[MAX_FILE][MAX_FILE], fileSum[MAX_FILE][MAX_FILE], output;

int dp(int start, int end);
int min(int a, int b) {
	return a < b ? a : b;
}

int main() {
	int tc;
	cin >> tc;
	for (int i = 0; i < tc; i++) {
		cin >> k;
		for (int j = 0; j < k; j++) {
			cin >> file[j];
		}
		cout << dp(0, k - 1) << endl;
		memset(DP, 0, sizeof(DP));
		memset(fileSum, 0, sizeof(DP));
	}
}

int dp(int start, int end) {
	if (start == end)
		return 0;
	if (DP[start][end] != 0)
		return DP[start][end];

	int cur = fileSum[start][end];
	if (cur == 0) {
		for (int i = start; i <= end; i++)
			cur += file[i];
		fileSum[start][end] = cur;
	}

	int result = 2000000000;
	for (int i = start; i < end; i++) {
		result = min(result, dp(start, i) + dp(i + 1, end));
	}

	//cout << start << "\t" << end << "\t" << result << "\t" << cur <<endl;
	return DP[start][end] = result + cur;
}
This post is licensed under CC BY 4.0 by the author.

11054 가장 긴 바이토닉 부분수열

1107 리모컨

Comments powered by Disqus.