문제 링크
풀이
비트 마스크를 하면서 dp를 돌면 된다.
백준[1648] 격자판 채우기와 거의 유사한 문제이다.
위의 문제와 차이점은 현재 칸을 안 채우고 넘어가는 경우가 있는 것이다.
코드
#include <bits/stdc++.h>
using namespace std;
int dp[15 * 15][1 << 14], n, m;
string value;
int calValue(string s) {
if (s[0] > s[1]) swap(s[0], s[1]);
if (s[0] == 'A') {
if (s[1] == 'A') return 10;
if (s[1] == 'B') return 8;
if (s[1] == 'C') return 7;
if (s[1] == 'D') return 5;
if (s[1] == 'F') return 1;
} else if (s[0] == 'B') {
if (s[1] == 'B') return 6;
if (s[1] == 'C') return 4;
if (s[1] == 'D') return 3;
if (s[1] == 'F') return 1;
} else if (s[0] == 'C') {
if (s[1] == 'C') return 3;
if (s[1] == 'D') return 2;
if (s[1] == 'F') return 1;
} else if (s[0] == 'D') {
if (s[1] == 'D') return 2;
if (s[1] == 'F') return 1;
} else return 0;
return 0;
}
int dpf(int k, int s) {
int &ret = dp[k][s];
if (~ret) return ret;
if (k == n * m && !s) return 0;
if (k >= n * m && s) return -1e9;
ret = 0;
ret = max(ret, dpf(k + 1, s >> 1));
if (s & 1) {
ret = max(ret, dpf(k + 1, s >> 1));
} else {
if (k % m != m - 1 && (s & 2) == 0) {
string v;
v.push_back(value[k]);
v.push_back(value[k + 1]);
ret = max(ret, dpf(k + 2, s >> 2) + calValue(v));
}
string v;
v.push_back(value[k]);
v.push_back(value[k + m]);
ret = max(ret, dpf(k + 1, (s >> 1) | (1 << (m - 1))) + calValue(v));
}
return ret;
}
int main() {
scanf("%d %d", &n, &m);
for (int i = 0; i < n; i++) {
string tmp; cin >> tmp;
value += tmp;
}
memset(dp, -1, sizeof dp);
printf("%d", dpf(0, 0));
}
'Algorithm > BOJ' 카테고리의 다른 글
백준[1021] 회전하는 큐 (0) | 2021.09.28 |
---|---|
백준[9663] N-Queen (0) | 2021.09.25 |
백준[1648] 격자판 채우기 (0) | 2021.09.10 |
백준[17413] 단어 뒤집기 2 (0) | 2021.09.06 |
백준 [2494] 숫자 맞추기 (0) | 2021.09.05 |