알고리즘 문제해결/BOJ

BOJ 3056 007

havana723 2022. 7. 29. 23:55

https://www.acmicpc.net/problem/3056

 

3056번: 007

비밀 요원 007은 제임스 본드로 유명한 비밀 요원이다. 최근 알려진 정보에 의하면 제임스본드는 대다수 미션을 자신이 직접 수행하지 않는다고 한다. 본드는 미션을 자신과 비슷하게 생긴 사촌

www.acmicpc.net

 

비트마스킹을 통한 다이나믹 프로그래밍으로 해결할 수 있는 문제입니다. 원래 DP를 탑다운으로 주로 짜는데, 바텀업 연습을 해보고자 바텀업으로 구현했습니다.

 

1번 사촌부터 N번 사촌까지 차례대로 일을 배정하며 i번째 사촌까지 일을 배정했을 때 어떤 일들이 배정되었는지를 비트마스킹을 통해 표현해주었습니다. i번째 일이 배정되었다면 i번째 비트를 켜주는 식으로 구현하면 됩니다. 각 state에 대해 최댓값을 저장해주면 됩니다.

 

아래는 코드입니다.

 

#include <bits/stdc++.h>
#define FastIO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define endl '\n'
#define ends ' '

using namespace std;

int T, n;
double prob[20][20], memo[1 << 20];

int32_t main(void) {
  FastIO;
  T = 1;
  //cin >> T;

  while (T--) {
    cin >> n;

    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        cin >> prob[i][j];
        prob[i][j] /= 100;
      }
    }

    for (int j = 0; j < n; j++) memo[1 << j] = prob[0][j];
    for (int i = 1; i < n; i++) {
      for (int state = 1; state < (1 << n); state++) {
        int cnt = 0;
        for (int j = 0; j < n; j++) if (state & (1 << j)) cnt++;
        if (cnt != i) continue;
        for (int j = 0; j < n; j++) {
          int newState = state | (1 << j);
          memo[newState] = max(memo[newState], memo[state] * prob[i][j]);
        }
      }
    }

    int finished = 0;
    for (int i = 0; i < n; i++) finished = finished | (1 << i);

    cout << fixed << setprecision(6);
    cout << memo[finished] * 100 << endl;
  }

  return 0;
}

 

플로우를 통해서도 풀 수 있다고 들었는데 플로우를 공부 안 해서 잘 모르겠습니다. 제한이 커져도 플로우로 풀 수 있다는 것 같습니다.

'알고리즘 문제해결 > BOJ' 카테고리의 다른 글

BOJ 5502 팰린드롬  (0) 2022.08.04
BOJ 8872 빌라봉  (0) 2022.08.03
BOJ 5859 Liars and Truth Tellers  (0) 2022.08.02
BOJ 1635 1 또는 -1  (0) 2022.08.01
BOJ 16939 2×2×2 큐브  (0) 2022.07.31