백준 15361번 Izbori
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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | #include <iostream> #include<algorithm> #include<cstring> using namespace std; int n, m, k; int arr[100][15]; int visited[100][15]; int cnt[16]; //no[] 0이면 후보 1이면 사퇴 bool no[16]; void win() { memset(cnt, 0, sizeof(cnt)); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (no[arr[i][j]] == 1) continue; cnt[arr[i][j]]++; break; } } } int DFS(int pos,int num) { //뽑아야하는 후보의 경우 다음케이스넘어감. if (pos == k) DFS(pos + 1, num); //모든 후보들의 사퇴여부를 결정했을때 if (pos == m + 1) { win(); int Maxcnt = 0; int eq=0; for (int i = 1; i <= m; i++) { if (Maxcnt < cnt[i]) { Maxcnt = cnt[i]; eq = i; } } if (eq == k ) { return num; } else return 987654321; } int ret = 98764321; for (int i = 0; i < 2; i++) { no[pos] = i; if (i == 0) { //pos번 후보가 사퇴하지않는 경우 ret=min(ret,DFS(pos + 1, num)); } else { //pos번 후보가 사퇴하는 경우 ret = min(ret, DFS(pos + 1, num + 1)); } } return ret; } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int no[16]; cin >> n >> m >> k; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> arr[i][j]; } } memset(no, 0, sizeof(no)); memset(cnt, 0, sizeof(cnt)); for (int i = 0; i < n; i++) { cnt[arr[i][0]]++; } int Max = 0; int pos = 0; for (int i = 1; i <= m; i++) { if (Max < cnt[i]) { Max = cnt[i]; pos = i; } } cout << pos << endl; cout << DFS(1, 0); return 0; } | cs |
출처:https://www.acmicpc.net/problem/15361
후보가 모두 표를 동일하게 받은 경우에 대한 경우를 고려하지않아서 계속 틀렸습니다.
사퇴여부를 모두 고려한다음 계산을 빠르게 해주는게 문제의 핵심 포인트입니다.
'알고리즘 > BAEKJOON' 카테고리의 다른 글
| 백준 12115번 Baza (0) | 2019.05.11 |
|---|---|
| 백준 6118번 숨바꼭질 (0) | 2019.05.11 |
| 백준 15360번 Rasvjeta (0) | 2019.05.10 |
| 백준 2562번 전깃줄 (0) | 2019.04.04 |
| 백준 16766번 Convention (0) | 2019.04.04 |