Skip to content

Commit 6a03814

Browse files
committed
13주차
1 parent 4c1bc7a commit 6a03814

File tree

3 files changed

+201
-0
lines changed

3 files changed

+201
-0
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# https://www.acmicpc.net/problem/1202
2+
3+
'''
4+
보석 도둑
5+
knabsack문제와 유사한 유형으로 보이는데
6+
가방에는 하나의 보석만 넣을 수 있다는 조건으로 인해 knapsack으로는 접근 불가
7+
8+
입력 조건
9+
보석 갯수, 가방 갯수
10+
1 <= N , K <= 300,000
11+
각 보석의 정보 M_i, V_i
12+
0 <= M_i, V_i <= 100,000,000
13+
14+
보석을 최대한 많이 훔칠 때의 가격의 합
15+
1. 그리디? 하게 넣어보기
16+
-보석에 대해 가장 적은 크기의 가방부터 그리디하게 채운다.
17+
-> 가장 적은 크기 가방에 대해 해당 허용 무게 중 가장 비싼걸 채워넣는다
18+
가능한 이유 -> 가방에 "보석 1개" 만 가능하기 때문에
19+
20+
일단 weight,value를 w, v라고 할 때
21+
22+
입력받은 w, v에 대해 w를 기준으로 쌍으로 정렬하여 heapq를 만든다
23+
입력
24+
jewels = []
25+
for _ in range(n):
26+
w, v = map(int, input().split())
27+
heapq.heappush(jewels, (w, v))
28+
그리고 가방 크기 또한 크기가 적은 순서대로 입력받는다.
29+
backpacks = []
30+
for _ in range(k):
31+
C_i = int(input())
32+
heapq.heappush(backpacks, C_i)
33+
34+
35+
이제 가방 크기에 대해 채우는 함수를 작성하자
36+
1. 전역적으로 사용할 우선순위 큐 하나 선언
37+
이 안에는 (가치, 무게) 쌍으로 최대 힙으로 값을 넣는다.
38+
v_w_max_pq = []
39+
2. 가방의 무게까지 jewels pq에서 하나씩 꺼내 v_w_max_pq에 채워 넣는다
40+
41+
3. 다 채운 이후 v_w_max_pq에서 하나를 꺼내서 해당 value를 최대값으로 지정한다.
42+
즉 result에 해당 value를 추가한다
43+
44+
v_w_max_pq = []
45+
result = 0
46+
def pick_jewels():
47+
global result
48+
49+
while backpacks:
50+
backpack_limit = heapq.heappop(backpacks)
51+
while jewels and jewels[0][0] <= backpack_limit:
52+
w, v = heapq.heappop(jewels)
53+
if v_w_max_pq: #만약 해당 가방 크기보다 작은 보석들이 존재할 때
54+
heapq.heappush(v_w_max_pq, (-v, w)) #파이썬은 최소힙, 따라서 -붙여 최대힙 구현
55+
result -= heapq.heappop(v_w_max_pq)
56+
57+
'''
58+
59+
import sys, heapq
60+
input = sys.stdin.readline
61+
62+
63+
def pick_jewels():
64+
global result
65+
66+
while backpacks:
67+
backpack_limit = heapq.heappop(backpacks)
68+
while jewels and jewels[0][0] <= backpack_limit:
69+
w, v = heapq.heappop(jewels)
70+
heapq.heappush(v_w_max_pq, (-v, w)) #파이썬은 최소힙, 따라서 -붙여 최대힙 구현
71+
if v_w_max_pq:
72+
result -= heapq.heappop(v_w_max_pq)[0]
73+
74+
if __name__ == "__main__":
75+
76+
n, k = map(int, input().split())
77+
78+
jewels = []
79+
for _ in range(n):
80+
w, v = map(int, input().split())
81+
heapq.heappush(jewels, (w, v))
82+
83+
backpacks = []
84+
for _ in range(k):
85+
C_i = int(input())
86+
heapq.heappush(backpacks, C_i)
87+
88+
89+
v_w_max_pq = []
90+
result = 0
91+
pick_jewels()
92+
print(result)
93+
94+
95+
96+

limnyn/13주차/1238_파티.py

Whitespace-only changes.
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# https://www.acmicpc.net/problem/22866
2+
'''
3+
1 <= N, L <= 100,000
4+
5+
n^2 불가
6+
7+
문제에서 요구하는 출력
8+
건물에서 "거리가 가장 가까운 건물의 번호" 중 "작은 번호"
9+
10+
-> 모든 건물을 비교할 필요 없이 "자신보다 큰" 건물 번호를 출력하면 된다
11+
12+
이 중 가까운 "작은 번호"를 출력하기
13+
14+
왼쪽 오른쪽 한번씩 탐색하면서 자신보다 가장 가까운 큰 것을 찾아보자
15+
16+
왼쪽에서 오른쪽으로 이동하는 동안
17+
18+
1. stack[-1], 즉 stack의 top이 현재 빌딩 높이보다 높을 때 까지 pop을 한다.
19+
2. 만약 현재 빌딩 높이보다 높은 빌딩이 stack에 존재한다면
20+
결과 리스트에 해당 빌딩의 index를 넣고 현재 빌딩을 stack에 넣는다.
21+
2-1
22+
현재 스택에 남아 있는 갯수 = 관측할 수 있는 빌딩의 수
23+
따라서 스택의 크기를 계산처리해준다.
24+
3. 만액 스텍에 현재 빌딩 높이보다 높은 빌딩이 없다면 결과 리스트에 0을 넣는다.
25+
26+
왼쪽 탐색
27+
def search_left():
28+
stack = []
29+
stack.append((buildings[0], 0))
30+
31+
for i in range(1, n):
32+
while stack:
33+
if stack[-1][0] <= buildings[i]:
34+
stack.pop()
35+
else:
36+
result[i] = stack[-1][1]
37+
building_counts[i] += len(stack)
38+
break
39+
stack.append((buildings[i], i))
40+
41+
오른쪽 탐색은 위 코드에서 가까운 거리가 오른쪽 탐색이 더 가까울 때 갱신하도록 추가하면 된다.
42+
while stack:
43+
if stack[-1][0] <= buildings[i]:
44+
stack.pop()
45+
else:
46+
if result[i] == -1 or abs(i - stack[-1][1]) < abs(i - result[i]):
47+
result[i] = stack[-1][1]
48+
break
49+
building_counts[i] += len(stack)
50+
stack.append((buildings[i], i))
51+
52+
'''
53+
54+
import sys
55+
input = sys.stdin.readline
56+
57+
def search_left():
58+
stack = []
59+
stack.append((buildings[0], 0))
60+
61+
for i in range(1, n):
62+
while stack:
63+
if stack[-1][0] <= buildings[i]:
64+
stack.pop()
65+
else:
66+
result[i] = stack[-1][1]
67+
building_counts[i] += len(stack)
68+
break
69+
stack.append((buildings[i], i))
70+
71+
72+
# print(result)
73+
74+
75+
def search_right():
76+
stack = []
77+
stack.append((buildings[-1], n-1))
78+
79+
for i in range(n-2, -1, -1):
80+
while stack:
81+
if stack[-1][0] <= buildings[i]:
82+
stack.pop()
83+
else:
84+
if result[i] == -1 or abs(i - stack[-1][1]) < abs(i - result[i]):
85+
result[i] = stack[-1][1]
86+
break
87+
building_counts[i] += len(stack)
88+
stack.append((buildings[i], i))
89+
90+
# print(result)
91+
92+
if __name__ == "__main__":
93+
n = int(input())
94+
buildings = list(map(int, input().split()))
95+
result = [-1]*n
96+
building_counts = [0] * n
97+
search_left()
98+
search_right()
99+
100+
101+
for idx, building_index in enumerate(result):
102+
if building_index == -1:
103+
print(0)
104+
else:
105+
print(f"{building_counts[idx]} {building_index + 1}")

0 commit comments

Comments
 (0)