1. 양궁 대회
brute-force하게 푼다면 서로 다른 11개의 구역 중 10개를 뽑는 방법(== 동일한 10개의 화살을 11개의 구역에 놓는 경우의 수). 즉 11H10이다. 충분히 계산 가능한 수치. 이 경우 11개의 구역 중 n개를 뽑고, 뽑은 것을 size 11짜리 vector로 변환도 해야하고, 갱신도 신경써줘야 한다. 만약 point 차가 같은 경우는 우선순위가 더 높은 벡터를 정답에 할당해 주어야 하는데, 이에 대한 함수도 만들어 주어야 한다.
즉 만들어야 하는 함수만 'vector 우선순위 계산 함수', '점수 계산 함수', '중복조합 함수'로 다 필요하긴 하지만 상당히 귀찮았다.
// 양궁대회 #include <string> #include <vector> #include <iostream> #include <algorithm> using namespace std; vector<int> apeach, answer; int point_differ = 0; typedef pair<int, int> pii; // a가 우선순위 -> true, b가 우선순위 -> false bool cmp(vector<int> &a, vector<int> &b){ //vector 거꾸로 보고 수가 더 커야 함 for(int i = 10; i>=0; i--){ if(a[i] > b[i]) return true; else if(a[i] == b[i]) continue; else return false; } } pii calResult(vector<int> lion){ int cur_point; pii result = {0, 0}; // .first : apeach, .second : lion point for(int i = 0; i<=10; i++){ cur_point = 10-i; if(apeach[i] + lion[i] == 0) continue; if(apeach[i] >= lion[i]) result.first += cur_point; else result.second += cur_point; } return result; } // arr : size n, 뽑을 숫자들 // result : size r, 뽑힌 숫자들. void duplicateCombination(int depth, int r, int prev_idx, vector<int>& arr, vector<int>& result){ if(depth == r){ vector<int> lion(11, 0); for(int i : result) lion[i]++; pii point = calResult(lion); int lion_point = point.second, apeach_point = point.first; if(point_differ < lion_point - apeach_point){ answer = lion; point_differ = lion_point - apeach_point; } if(point_differ == lion_point - apeach_point){ answer = cmp(lion, answer)? lion : answer; } return; } for(int i = prev_idx; i<arr.size(); i++){ result[depth] = arr[i]; duplicateCombination(depth+1, r, i, arr, result); } } vector<int> solution(int n, vector<int> info) { answer = {-1}; apeach = info; vector<int> areas = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; vector<int> combinations(n); duplicateCombination(0, n, 0, areas, combinations); return answer; } /* 11개의 서로 다른 구역 중 n개를 뽑는 방법 (=같은 화살 10개를 11개의 구역에 놓는 방법) -> 중복조합. -> 11H10 */
좀 더 접근한다면, 각 구역에 대해 점수를 얻을지 말지 경우의 수 2개 * 구역 10개 -> 2^10이다.(다만 점수를 얻기 위해서는 잔여 화살 수가 여유가 있어야 한다) 좀 더 적은 수로 계산을 해 볼 수 있다.
// 양궁대회 #include <string> #include <vector> #include <iostream> #include <algorithm> using namespace std; typedef pair<int, int> pii; vector<int> apeach, answer; int point_differ = -1; // a가 우선순위 -> true, b가 우선순위 -> false bool cmp(vector<int> &a, vector<int> &b){ //vector 거꾸로 보고 수가 더 커야 함 for(int i = 10; i>=0; i--){ if(a[i] > b[i]) return true; else if(a[i] == b[i]) continue; else return false; } } pii calResult(vector<int> lion){ int cur_point; pii result = {0, 0}; // .first : apeach, .second : lion point for(int i = 0; i<=10; i++){ cur_point = 10-i; if(apeach[i] + lion[i] == 0) continue; if(apeach[i] >= lion[i]) result.first += cur_point; else result.second += cur_point; } return result; } void DFS(int depth, int max_depth, int num_arrows, vector<int>& lion){ if(depth == max_depth || num_arrows == 0){ lion[10] = num_arrows; pii point_result = calResult(lion); int apeach_point = point_result.first, lion_point = point_result.second; if(apeach_point >= lion_point) return; if(lion_point - apeach_point > point_differ){ point_differ = lion_point - apeach_point; answer = lion; } else if(lion_point - apeach_point == point_differ){ answer = cmp(answer, lion)?answer : lion; } return; } // 점수를 얻을 수 있어서 점수를 얻겠다고 선택하는 경우 int apeach_point = apeach[depth]; if(num_arrows >= apeach_point + 1){ lion[depth] = apeach_point + 1; DFS(depth+1, max_depth, num_arrows - apeach_point - 1, lion); lion[depth] = 0; } // 점수를 얻을 수 있든 말든 점수를 얻지 않는다고 선택하는 경우 DFS(depth+1, max_depth, num_arrows, lion); } vector<int> solution(int n, vector<int> info) { apeach = info; vector<int> lion(11, 0); answer = {-1}; DFS(0, 9, n, lion); return answer; }
근데 코드 길이는 비슷하긴 하다. 아무튼 이렇게 2가지 방식으로 풀었다.
2. 디스크 컨트롤러
SJF를 pq로 구현하면 되는 문제다.
1) 만약 pq에 값이 있다면 값을 빼고 현 시간, 대기시간 등을 계산해 주고,
2) 현 시간보다 짧은 모든 job들을 pq에 넣는다.
3) 만약 pq가 빈 상태라면 다음 job의 입력시간이 현 시간보다 긴 것이다. 이 상태는 무한루프를 돌기 때문에 다음 job의 입력시간을 현 시간으로 수정해 준다.
3. 정수 삼각형
간단한 DP이다.
4. 네트워크
간단한 DFS이다.
'PS > PS Log' 카테고리의 다른 글
22.05.08. 풀었던 문제들 (0) | 2022.06.23 |
---|---|
22.05.07. 풀었던 문제들 (0) | 2022.06.23 |
22.05.05. 풀었던 문제들 (0) | 2022.06.23 |
22.05.03. 풀었던 문제들 (0) | 2022.06.23 |
22.05.02. 풀었던 문제들 (0) | 2022.06.23 |