단말 노드 간의 최대 합을 찾는 문제

트리를 만든 후에, 후위 순회 하듯이 재귀를 통하여 문제를 해결한다

단말 노드 간의 최대 합을 찾는 방법 : https://junho0956.tistory.com/299?category=879042

 

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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <algorithm>
#include <set>
#include <cmath>
#include <limits>
#include <cstring>
#include <string>
using namespace std;
 
struct tree {
    long long w;
    tree* parent = NULL;
    tree* left = NULL;
    tree* right = NULL;
};
 
struct pii {
    long long l, r;
};
 
tree* left_tree(int l, int r, int idx);
tree* right_tree(int l, int r, int idx);
int tree_size;
int order[100001];
tree node[100001];
tree* root;
long long answer;
int max_node;
 
tree* right_tree(int l, int r, int idx) {
    return left_tree(l, r, idx);
}
 
tree* left_tree(int l, int r, int idx) {
    if (!(l <= r && idx < tree_size)) return NULL;
    tree* now = &node[order[idx]];
 
    if (l == r) return now;
 
    int next = order[idx];
    now->left = left_tree(l, next - 1, idx + 1);
    now->right = right_tree(next + 1, r, idx + (next - l) + 1);
 
    if (now->left != NULL) now->left->parent = now;
    if (now->right != NULL) now->right->parent = now;
 
    return now;
}
 
void make_tree() {
    root = &node[order[0]];
 
    root->left = left_tree(0, order[0- 11);
    root->right = right_tree(order[0+ 1, tree_size - 1, order[0+ 1);
 
    if (root->left != NULL) root->left->parent = root;
    if (root->right != NULL) root->right->parent = root;
}
 
void init() {
    cin >> tree_size;
    
    for (int i = 0; i < tree_size; i++cin >> node[i].w, node[i].left = node[i].right = node[i].parent = NULL;
    for (int i = 0; i < tree_size; i++cin >> order[i];
}
 
 
pii searching(tree* now) {
    if (now->left == NULL && now->right == NULL) {
        answer = max(answer, now->w);
        return { now->w, now->w };
    }
 
    pii ret, L, R;
    if (now->left != NULL && now->right != NULL) {
        L = searching(now->left);
        R = searching(now->right);
        if (L.l >= R.l) ret.l = now->+ L.l;
        else ret.l = now->+ R.l;
        ret.r = now->+ L.l + R.l;
        answer = max(answer, ret.r);
    }
    else if (now->left != NULL && now->right == NULL) {
        L = searching(now->left);
        ret.l = ret.r = now->+ L.l;
    }
    else if (now->right != NULL && now->left == NULL) {
        R = searching(now->right);
        ret.l = ret.r = now->+ R.l;
    }
 
    return ret;
}
 
void solve() {
    answer = -987654321;
 
    pii ret = searching(root);
    answer = max(answer, ret.r);
    cout << answer << "\n";
}
 
int main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
 
    int tc;
    cin >> tc;
 
    while (tc--) {
        init();
        make_tree();
        solve();
    }
 
    return 0;
}
 

'algorithm' 카테고리의 다른 글

의료봉사(과제)  (0) 2020.04.27
convex hull  (0) 2020.04.07

BOJ : https://www.acmicpc.net/problem/14750

 

과제로 이 문제를 풀게 되어서 간단하게 방법만 소개하고자 한다

 

알아야할 정보는 다음과 같다

 

1. N K H M 순으로 인풋이 주어진다

2. N개만큼 다각형의 좌표가 주어진다(반시계방향)

3. H개만큼 홀의 갯수가 주어진다

4. M개만큼 쥐의 마리수가 주어진다

5. 각 홀은 최대 K마리의 쥐가 숨을 수 있다

6. 각 쥐는 당장 시야에 보이는 홀에만 들어갈 수 있다

   조건으로는 쥐와 홀에 대해서 선을 그엇을때 다른 벽이나 모서리와 겹치지 않아야한다.

7. 각 쥐는 반드시 다각형 내부에 존재한다 -> 다각형 선분위에 존재하지 않는다

8. 각 홀은 반드시 벽(선분)에 존재한다

9. 두개이상의 홀이나 쥐가 같은 위치에 존재하지 않는다

 

이때 모든 쥐가 숨을 수 있나 없나를 묻는 문제로,

문제를 해결하기 위해 필요한 지식은 

선분 교차확인법, 이분매칭 이렇게 2가지이다.

 

쥐와 홀의 쌍에 대해서 모든 벽과 선분교차를 확인하여

쥐가 들어갈 수 있는 홀을 따로 찾아둔 후에,

이분매칭을 통해서 쥐가 최대로 숨을 수 있는 마리수를 찾는다.

이때 이분매칭의 값이 쥐의 마리수와 같다면 possible이 된다

'algorithm > BOJ' 카테고리의 다른 글

BOJ 1103번 게임  (0) 2021.03.16
BOJ 2194번 유닛 이동시키기 C++  (0) 2020.07.05
BOJ 1647번 도시 분할 계획  (0) 2020.04.11
BOJ 1922번 네트워크 연결  (0) 2020.04.11
BOJ 1197번 최소 스패닝 트리  (0) 2020.04.10

 

 

현재 봉사할려는 곳에 대해서 지원한 팀, 지역, 방문 이런 값들을

잘 관리해주면서 재귀를 통해서 해결했다 

'algorithm' 카테고리의 다른 글

최대 합 경로 찾기(과제)  (0) 2020.04.29
convex hull  (0) 2020.04.07

uva : https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=14&page=show_problem&problem=1146

 

과제로 나와서 간단하게 설명해둬야겠다

 

해석만 할줄 알면 쉽게 풀 수 있는 문제다

 

부족한 영어실력이지만 간단히 해석해보면

표준 카드덱은 52장, 13개의 값을 각각 4종류로 가지고 있다

값은 2,3,4,5,6,7,8,9,10,잭,퀸,킹,에이스 로 이루어져있다

종류(suit)는 클로버, 다이아, 하트, 스페이드 로 이루어져있다

카드덱은 값과 종류로 서로 식별가능하며 <값, 종류> 의 형태로 이루어진다

예를 들어 king of spades, 9of hearts 가 있다

관례적으로 기본 덱은 종류(suit) -> 알파벳 순서, 값 -> 위의 주어진 형태 순으로 정렬되어있다

중간부분은 딱히 필요없다 

문제에서 요구하는 부분은 다음과 같다

 

1. 테스트케이스가 주어진다

2. 카드덱을 섞을 수 있는 n가지 방법이 주어진다.

3. 1~52의 카드가 중복없이 n번 주어진다 ( 52개당 한 세트?에 속한다고 보면된다)

4. 덱을 섞을 수가 1~n 사이의 수로 \n이 나오기전까지 계속 주어진다

5. 각 주어진 세트 번호로 현재 덱을 섞는다

6. \n으로 더이상 섞지 않는다면 현재 덱을 출력한다

7. 반복

 

'algorithm > uva' 카테고리의 다른 글

uva 11994번 Happy Painting!  (0) 2020.04.06
uva 384번 Slurpys, BOJ 14906번 스러피  (0) 2020.03.31
uva 10150번 Doublets  (0) 2020.03.27
uva 10469번 To Carry or not to Carry  (0) 2020.03.23
uva 10010번 Where's Waldorf?  (0) 2020.03.23

+ Recent posts