티스토리 뷰

알고리즘/BOJ

[백준] 1852 수 묶기

세진짱 2018. 7. 1. 20:19


수를 1X2 or 2X1 크기의 블럭으로 묶고 , 묶인 수들의 차의 합의 최대 / 최소를 찾는문제다


비트dp를 이용해서 풀 수 있다!

테이블은 d[위치][상태] 이다 -> 여기서 상태는 (위치~위치+3)까지의 상태

0부터 마지막 칸까지 가며 상태를 보고 내가 할 수 있는 행동들을 하면 된다

내 위치에서의 상태는 2가지다


1) 내가 있는 칸이 안채워진 경우

여기서 x,y를 보고 또 판단 해야 한다

n번째 줄이 아니라면 세로 가능~!

2번째 칸이 아니고 옆칸이 비었으면 가로 가능~! 


a) 가로로 놓을 수 있는 경우 (내 옆칸도 비었을 때)

b) 세로로 놓을 수 있는 경우 (위에서부터 보며 내려오므로 무조건 가능)


2) 채워진 경우

이 때는 바로 다음 블럭으로 넘어간다 (pos+1,(state>>1))


이렇게 최대 , 최소 총 2번 구하면 된다!

문제는 숫자가 크기 때문에 long long 써야한다!


소스코드

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <cmath>
using namespace std;
#define ll long long
#define MAXN 100010
const ll inf = 1e15;
int n;
ll arr[MAXN][3], d[MAXN * 3][(1 << 3)], p[MAXN * 3][(1 << 3)];
 
ll dgo(int pos, int state) {
    if (pos == n * 3return 0;
    ll &ret = d[pos][state];
    if (ret != -1return ret;
    ret = -inf;
    int x = pos / 3;
    int y = pos % 3;
    if (!(state & 1)) {
        if (x != n - 1) {
            ll temp = dgo(pos + 1, (state >> 1| (1 << 2));
            temp += abs(arr[x][y] - arr[x + 1][y]);
            ret = max(ret, temp);
        }
        if (y != 2 && !(state & 2)) {
            ll temp = dgo(pos + 2, (state >> 2));
            temp += abs(arr[x][y] - arr[x][y + 1]);
            ret = max(ret, temp);
        }
    }
    else ret = dgo(pos + 1, (state >> 1));
    return ret;
}
 
ll pgo(int pos, int state) {
    if (pos == n * 3return 0;
    ll &ret = p[pos][state];
    if (ret != -1return ret;
    ret = inf;
    int x = pos / 3;
    int y = pos % 3;
    if (!(state & 1)) {
        if (x != n - 1) {
            ll temp = pgo(pos + 1, (state >> 1| (1 << 2));
            temp += abs(arr[x][y] - arr[x + 1][y]);
            ret = min(ret, temp);
        }
        if (y != 2 && !(state & 2)) {
            ll temp = pgo(pos + 2, (state >> 2));
            temp += abs(arr[x][y] - arr[x][y + 1]);
            ret = min(ret, temp);
        }
    }
    else ret = pgo(pos + 1, (state >> 1));
    return ret;
}
int main() {
    memset(d, -1sizeof(d));
    memset(p, -1sizeof(p));
    scanf(" %d"&n);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < 3; j++) {
            scanf(" %lld"&arr[i][j]);
        }
    }
    printf("%lld\n", dgo(00));
    printf("%lld\n", pgo(00));
}
cs


'알고리즘 > BOJ' 카테고리의 다른 글

[백준] 1260 DFS와 BFS  (0) 2018.07.02
[백준] 2637 장난감조립  (0) 2018.07.01
[백준] 1600 말이 되고픈 원숭이  (0) 2018.07.01
[백준] 2411 아이템먹기  (0) 2018.07.01
[백준] 10747 Censoring  (0) 2018.06.30
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/02   »
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
글 보관함