※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 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
'BOJ' 카테고리의 다른 글
[BOJ 25184 // C++] 동가수열 구하기 (0) | 2022.08.14 |
---|---|
[BOJ 4850 // C++] Baskets of Gold Coins (0) | 2022.08.14 |
[BOJ 6494 // C++] Another lottery (0) | 2022.08.14 |
[BOJ 12725 // C++] Milkshakes (Small) (0) | 2022.08.14 |
[BOJ 12726 // C++] Milkshakes (Large) (0) | 2022.08.14 |