인간은 지금 당장 직면한 문제를 해결하는데 아주 특화되어 있다.
단, 미래의 일은 해결해내기를 아주 귀찮아하고 잘 하지도 못한다.
위 인용문은 필자가 즐겨 듣는 모 재테크 유튜버의 생각이다.
사람은 지금 당장의 기분이 중요하며(뭐, 동물이니까 당연한거 아닐까!) 지금 당장 직면한 문제는 빠르게 착수하여 해결해내기 때문에 일반적인 사람들은 소비를 줄이기 힘들다는게 말의 골자다.
그런 인간의 특성을 잘 반영시킨 알고리즘이 바로 욕심쟁이 알고리즘이다.
구한 정답이 최적의 정답이라는 것은 보장할 수 없다.
따라서, 구한 정답이 최적의 정답이라는 것은 증명이 필요하다.
장단점이 아주 확연한 알고리즘임을 알 수 있다.
게다가 “현재 취할 수 있는 최선의 선택을 취한다.” 라는 점에 선조 프로그래머들이 취했는지 다음과 같은 기본 형태를 정의하였다. (사실 로직이 아주 간단하기에 설계할 수 있었겠지만 말이다)
유리수 p/q가 주어졌을 때, 분자가 1인 분수들의 합으로 p/q를 표현하시오.
예) 5/6 = 1/2 + 1/3, 3/4 = 1/2 + 1/4
해법1 방식은 브루트 포스 방식의 성격이 강하다.
그러기 때문에 분모의 값이 큰 경우 비효율적인 접근 방식이 된다.
예시)
5/6에 대해서,
1/3에 대해서,
import math
def gauss(a, b):
if (a % b == 0):
return a // b
else:
return a // b + 1
p, q = map(int, input().split())
cnt = 0
while (p != 0):
n = gauss(q, p)
l = math.lcm(q, n)
least = [l // q, l // n]
p = p * least[0] - 1 * least[1]
q *= least[0]
cnt += 1
print(cnt)
한 개의 회의실이 있는데, n개의 회의 일정이 있고 이 회의실을 이용하여 회의한다.
각 회의 i에 대해서 시작 시간 와 끝 시간 가 주어진다.
각 회의가 겹치지 않게 하면서 가장 많은 횟수의 회의를 할 수 있도록 일정을 구하는 프로그램을 작성하라
- 입력
- 첫 줄에는 회의의 수 n
- 둘째 줄부터 n+1 줄 까지 두 정수 와
- 출력
- 잡은 회의를 차례대로 출력 (둘 이상의 답이 있을 수 있다)
모든 회의를 끝나는 시간에 따라 정렬해서 {1 , … , n} 을 얻습니다.
그렇다면 정답은 1을 포함하거나 포함하지 않거나 둘 중 하나입니다.
정답을 포함하지 않는다면..
정답을 포함한다면…
class meeting:
def __init__(self, s, f):
self.start = s
self.finish = f
def to_string(self):
return "({}, {})".format(self.start, self.finish)
n = int(input())
l = []
res = []
for _ in range(n):
s, f = map(int, input().split())
l.append(meeting(s, f))
# 일단 sort합니다. 편의상 reverse까지 해줍니다.
l.sort(key=lambda it: it.finish, reverse=True)
res.append(l.pop())
i = 0
while len(l) > 0:
candi = l.pop()
last = res[i]
if (candi.start < last.finish):
# 회의가 서로 겹치는 경우
continue
else:
# 회의가 서로 겹치지 않는 경우
res.append(candi)
i += 1
for e in res:
print(e.to_string(), end=' ')