티스토리 뷰
수를 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 * 3) return 0; ll &ret = d[pos][state]; if (ret != -1) return 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 * 3) return 0; ll &ret = p[pos][state]; if (ret != -1) return 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, -1, sizeof(d)); memset(p, -1, sizeof(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(0, 0)); printf("%lld\n", pgo(0, 0)); } | 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 |
댓글