※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 6132번 문제인 전화선이다.
문제는 아래 링크를 확인하자.

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

 

6132번: 전화선

[3, 3, 5, 3, 4] 로 전신주의 높이를 바꾸면 15에 문제를 해결할 수 있으며 이것이 최소다.

www.acmicpc.net

dp[i][h]를 "i번째 전신주까지 작업을 했을 때, i번 전신주가 높이 h인 경우의 비용의 최솟값"이라 정의하자.

 

이때 dp[i+1][h]는 min(dp[i][h'] + C*(h와 h'의 높이차) + (i+1번째 전신주와 h 사이의 높이차)^2)가 됨을 관찰할 수 있다. (단, h'은 i번 전신주의 초기 높이 이상, h는 i+1번 전신주의 초기 높이 이상)

 

위의 식을 빠르게 계산하기 위해 최적화를 할 수 있으나, boj에서는 위와 같은 dp테이블을 채워나가게끔 구현하는 것만으로도 제한시간 내로 통과할 수 있다. (사용하는 연산이 사칙연산뿐이라 속도가 빠르다.)

 

아래는 제출한 소스코드이다.

#include <iostream>
#include <cstring>
#include <utility>
using namespace std;

int N, C;
int dp[101];
int nxt[101];

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> N >> C;
	while (N--) {
		memset(nxt, 0x3f, sizeof(nxt));
		int H; cin >> H;
		int d = 0;
		for (int i = H; i < 101; i++) {
			int& nxti = nxt[i];
			for (int j = 1; j < 101; j++) {
				nxti = min(nxti, dp[j] + C * abs(i - j));
			}
			nxti += d * d;

			d++;
		}
		swap(dp, nxt);
	}

	int ans = 1000000007;
	for (int i = 1; i < 101; i++) ans = min(ans, dp[i]);
	cout << ans;
}
728x90

+ Recent posts