거의 알고리즘 일기장

백준 11066번 _ 파일 합치기 본문

알고리즘 문제풀이

백준 11066번 _ 파일 합치기

건우권 2020. 5. 4. 00:59

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

 

11066번: 파일 합치기

문제 소설가인 김대전은 소설을 여러 장(chapter)으로 나누어 쓰는데, 각 장은 각각 다른 파일에 저장하곤 한다. 소설의 모든 장을 쓰고 나서는 각 장이 쓰여진 파일을 합쳐서 최종적으로 소설의 완성본이 들어있는 한 개의 파일을 만든다. 이 과정에서 두 개의 파일을 합쳐서 하나의 임시파일을 만들고, 이 임시파일이나 원래의 파일을 계속 두 개씩 합쳐서 소설의 여러 장들이 연속이 되도록 파일을 합쳐나가고, 최종적으로는 하나의 파일로 합친다. 두 개의 파일을

www.acmicpc.net

 주의사항

 소설이므로 장이 섞이면 안된다. -> 그러므로 바로 옆에 있는것하고만 파일을 합칠수있다!


 접근

 총 파일이 4개라고 하면 파일이 합쳐지는 경우의 수는

 ( (1, 2) (3, 4) ) , ( ( 1, (2, 3) ), 4), .....등등등 여러가지방법이 나오게 된다.

 이를 하나하나 해보기에는 너무나도 많은 겹치는 연산들이 있을것이다. 그렇다면 이 겹치는 연산을 줄이기 위해서는 동적계획법을 이용하는게 적절해 보인다.


 풀이방법

 일단 dp[start][end]는 start부터 end까지 합쳐지는데 최솟값이다.

 

 점화식을 세워보면

 dp[i][j] = dp[i][mid] + dp[mid+1][j] + (i~j까지의 부분합)이다.

 그리고 이를 3중 for문을 이용해서 풀면 답이 나온다.

 

 1번째 for문 : gap

 2번째 for문 : start 

 3번째 for문 : mid -> start <=mid < end ( mid < end인 이유는 mid+1로 자르기 때문 )


 간단한 예시동작  

 아마 위의 글만 읽어서는 와닿지 않을 것이다. 간단한 예시를 들어보겠다.

 

 ex) 총 4장, 순서대로 40, 30, 30, 50

 

 

 

 

 여기까지 하게되면 dp[1][4]가 정답이다.


 전체코드

#include <iostream>
#include <algorithm>
#include <limits.h>

using namespace std;

int dp[501][501];
int cost[501];
int sum[501];

int main()
{
	int testcase;
	cin >> testcase;
	for (int t = 0; t < testcase; t++)
	{
		int k;
		cin >> k;

		//make cost
		for (int i = 1; i <= k; i++)
		{
			cin >> cost[i];
		}

		//make sum
		for (int i = 1; i <= k; i++)
		{
			if (i == 1)
				sum[i] = cost[i];
			else
				sum[i] = sum[i - 1] + cost[i];
		}

		//solve
		for (int gap = 1; gap < k; gap++)
		{
			for (int start = 1; start + gap <= k; start++)
			{
				int end = start + gap;

				dp[start][end] = INT_MAX;

				for (int mid = start; mid < end; mid++)
				{
					dp[start][end] = min(dp[start][end], dp[start][mid] + dp[mid + 1][end] + sum[end] - sum[start-1]);
				}
			}
		}
		cout << dp[1][k] << endl;

		/*for (int i = 1; i <= k; i++)
		{
			for (int j = 1; j <= k; j++)
			{
				cout << dp[i][j] << ' ';
			}
			cout << endl;
		}*/
	}
	return 0;
}

 후기

 "난 진짜 재능이 없구나ㅠ.." 풀면서 이 생각만 났다. 뭔 답을 읽어도 뭔 소리진지 당최 모르겠어서 눈물이 찔끔났다. 

 

 결국 답을 보고 겨우겨우 이해해서 풀기는 했지만, 접근방식이나 dp에 대한 이해도, 전체적인 실력이 모두 삼위일체로 허접이라는것을 다시한번 깨닫게 해주는 문제였다. 종만북 dp파트도 진도가 안나가는 이유가 있었다.ㅋㅋㅋㅋㅋㅋ

 

 이번년도 안에 코드포스 블루.. 갈수있을까? 

반응형

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

백준 1520번 _ 내리막 길  (0) 2020.05.04
백준 11049번 _ 행렬 곱셈 순서  (0) 2020.05.04
백준 2293번 _ 동전 1  (0) 2020.05.03
백준 11657번 _ 타임머신  (0) 2020.05.03
codeforces_ 158B_ Taxi  (0) 2020.05.02
Comments