알고리즘/다이나믹 프로그래밍
[B9465] - 스티커
tongnamuu
2018. 9. 9. 18:27
https://www.acmicpc.net/problem/9465 스티커입니다. 스티커를 최대한의 점수를 갖게 떼어내는 방법을 구하는 것이 목표입니다.
최종답을 구할 때 이전 상태를 이용해야하기 때문에 dp로 풀 수 있습니다.
어떤 위쪽 칸에 들어가는 최대값을 구하고 싶다면 그 전전칸의 위쪽의 최대값+전 칸의 아래쪽 값과 그 전 칸의 아래쪽 값 중 큰 값에 a[i][0]을 더해주면 됩니다.
d[i][0]=max(d[i-2][0]+a[i-1][1],d[i][1])+a[i][0]으로 표현할 수 있네요
그런데 이 값보다 전칸의 위쪽값이 더 크다면 어떨까요?
즉 a[i][0]의 스티커를 떼어내지 않는 경우도 있을 수 있습니다.
그러므로 d[i][0]=max(d[i-1][0],max(d[i-2][0]+a[i-1][1],d[i][1])+a[i][0]) 이 되겠군요
아래쪽도 마찬가지로 식을 세우면 되겠습니다.
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 | #include <iostream> using namespace std; int a[100001][2] = { 0, }; int d[100001][2] = { 0, }; int max(int a, int b) { if (a > b) return a; else return b; } int main() { int T; cin >> T; for (int test_case = 1; test_case <= T; ++test_case) { int n; cin >> n; for (int i = 0; i < n; i++) { cin >> a[i][0]; d[i][0] = 0; d[i][1] = 0; } for (int i = 0; i < n; i++) { cin >> a[i][1]; } d[0][0] = a[0][0]; d[0][1] = a[0][1]; d[1][0] = max(a[1][0] + a[0][1], a[0][0]); d[1][1] = max(a[0][0] + a[1][1], a[0][1]); for (int i = 0; i + 2 < n; i++) { d[i + 2][0] = max(d[i + 1][0], max(d[i][0] + a[i + 1][1], d[i][1]) + a[i + 2][0]); d[i + 2][1] = max(d[i + 1][1], max(d[i][1] + a[i + 1][0], d[i][0]) + a[i + 2][1]); } int ans = max(d[n - 1][1], d[n - 1][0]); cout << ans << '\n'; } } | cs |