반응형

유형 : dp

 

문제풀이

* 지금 설명할 풀이는 효율이 좋지 못합니다.

 b 도시에 i번째로 도착했을 때, 가능한 기내식 점수들의 합은 dp[a][i-1]+air[a][b] 가 됩니다. (air[a][b]는 a에서 b 구간 비행기의 기내식의 점수)

 따라서 dp[b][i]의 점화식은 아래와 같이 쓸 수 있습니다.

 dp[b][i] = max(dp[a][i-1]+air[a][b] for b보다 작은 모든 a)

 다만 위의 식을 진행하는 데에 있어서, i-1번째로 a에 도착한 경우와 a에서 b구간의 비행기가 있다는 조건을 위한 조건문이 추가로 들어가야합니다.

 위의 점화식을 b를 n까지, i는 m까지 반복 한 후, dp[n]의 최댓값을 반환하면 됩니다.

 

Python Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import sys
n,m,k = map(int,sys.stdin.readline().split())
air = [[0 for i in range(n+1)] for j in range(n+1)]
#dp[도시][몇번째]
dp = [[0 for i in range(k+1)] for j in range(n+1)]
for _ in range(k):
    a,b,c = map(int,sys.stdin.readline().split())
    air[a][b] = max(air[a][b],c)
for b in range(2, n+1):
    dp[b][2= air[1][b]
for b in range(2,n+1):
    for i in range(3,m+1):
        try:
            dp[b][i] = max(dp[a][i-1]+air[a][b] for a in range(1,b) if air[a][b] and dp[a][i-1])
        except:
            pass
print(max(dp[n]))
cs

line13에 try 문이 들어간 이유는 if문을 만족하는 a가 하나도 없는 경우 max함수에서 에러가 발생하기 때문입니다.

 

문제링크

 

2157번: 여행

첫째 줄에 N(1≤N≤300), M(2≤M≤N), K(1≤K≤100,000)가 주어진다. K는 개설된 항공로의 개수이다. 다음 K개의 줄에는 각 항공로에 대한 정보를 나타내는 세 정수 a, b, c(1≤a, b≤N, 1≤c≤10,000)가 주어진다. 이는 a번 도시에서 b번 도시로 이동하는 항로가 있고, 서비스되는 기내식의 점수가 c점이라는 의미이다. 서쪽에서 동쪽으로 이동하는 항로가 입력될 수도 있고, 같은 도시 쌍 사이에 항로가 여러 개 있을 수도 있

www.acmicpc.net

 

반응형

'알고리즘 > 백준' 카테고리의 다른 글

백준 2293 동전 1  (0) 2020.03.01
백준 1038 감소하는 수  (0) 2020.02.28
백준 2579 계단 오르기  (0) 2020.02.27
백준 4949 균형잡힌 세상  (0) 2020.02.25
백준 2839 설탕배달  (0) 2020.02.24
반응형

유형 : dp

 

문제풀이

 포도주 시식 문제와 유사하지만, 마지막 계단을 반드시 밟아야한다는 제한이 있다. 

 따라서 i번째 계단의 점수가 s[i]라 하면, i번째 계단을 밟았을 때의 최대 점수 dp[i]는 다음과 같이 주어진다.

 dp[i] = max(dp[i-2]+s[i], dp[i-3]+s[i-1]+s[i])

 즉, 2칸 전 계단을 밟고 이번 계단을 밟거나, 3칸 전 계단을 밟고 전칸을 밟고 이번 계단을 밟거나 두가지 조건이 가능하다.

 

list 초기화와 append

 위의 문제를 해결하는데 있어서, dp를 먼저 빈 list로 선언한 후 append로 하나씩 채워갈 수도 있고, dp를 길이가 n인 리스트로 선언한 후, i번째 요소를 바꿔가는 방법이 있는데, 후자가 효율적이다. 전자로 통과한 후, 후자의 방법으로 바꾸었더니 80ms 에서 56ms로 줄었다.

 

Python Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import sys
= int(sys.stdin.readline())
= [0 for i in range(n)]
dp = [0 for i in range(n)]
 
for i in range(min(3,n)):
    s[i]=int(sys.stdin.readline())
if n>3:
    dp[0]=s[0]
    dp[1]=s[0]+s[1]
    dp[2]=max(s[0]+s[2],s[1]+s[2])
    for i in range(3,n):
        s[i] = int(sys.stdin.readline())
        dp[i]=max(dp[i-2]+s[i],dp[i-3]+s[i-1]+s[i])
elif n==3:
    dp=[s[0],s[0]+s[1],max(s[0]+s[2],s[1]+s[2])]
else:
    dp=[sum(s)]
print(dp[-1])
cs

 

반응형

'알고리즘 > 백준' 카테고리의 다른 글

백준 1038 감소하는 수  (0) 2020.02.28
백준 2157 여행  (0) 2020.02.27
백준 4949 균형잡힌 세상  (0) 2020.02.25
백준 2839 설탕배달  (0) 2020.02.24
백준 11052 카드 구매하기  (0) 2020.02.24
반응형

유형 : 스택

 

풀이과정

 Stack이란 후입선출하는 자료구조로 이를 이용하여 괄호의 균형을 체크한다.

 stack은 그냥 list를 선언하여 활용했는데, 어차피 맨 뒤의 것만 지울것이기 때문이다(list.pop()). 만약 앞의 것을 지워야한다면 deque를 선언하여 활용하는 것이 좋다.

 1. 문자열의 앞에서 부터 확인하는데, 왼괄호('(','[')를 만나면 stack에 넣어준다.

 2. 오른괄호를 만나면 stack의 맨 뒤의 원소를 확인하여 둘이 짝이면 stack의 맨 뒤의 것을 제거한 후 넘어가고(list.pop()), 짝이 맞지 않는다면 균형이 잡히지 않은 괄호이기 때문에 'no'를 리턴해준다.

 

입출력

 문제자체는 굉장히 쉬운 문제인데, 이상한데서 고생을 했다. 바로 입출력 문제인데, Python3에서 input()으로 입력을 받을 경우에는 뒤에 개행문자가 없지만 sys.stdin.readline()으로 입력을 받을 경우에는 뒤에 개행문자가 추가되어 입력이 들어온다. 따라서 이를 유의해야한다.

 

Python Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def solution(string):
    stack = []
    for s in string:
        if s=='(' or s=='[':
            stack.append(s)
        elif s==')':
            if len(stack)>0 and stack[-1]=='(':
                stack.pop()
            else:
                return 'no'
        elif s==']':
            if len(stack)>0 and stack[-1]=='[':
                stack.pop()
            else:
                return 'no'
    return 'yes' if len(stack)==0 else 'no'
 
import sys
if __name__=='__main__':
    while 1:
        string = sys.stdin.readline()[:-1]
        if string == '.':
            break
        print(solution(string[:-1]))
cs

 

 

반응형

'알고리즘 > 백준' 카테고리의 다른 글

백준 2157 여행  (0) 2020.02.27
백준 2579 계단 오르기  (0) 2020.02.27
백준 2839 설탕배달  (0) 2020.02.24
백준 11052 카드 구매하기  (0) 2020.02.24
백준 7576 토마토  (0) 2020.02.21
반응형

 

 

주어진 N을 5와 3만을 사용하면서 가장 적은 수의 5와 3으로 나타내는 문제이다.

 

풀이과정

 $N = 5x + 3y$ 라 할때, $x$가 클수록 $x+y$가 작아질 것이다. 예를 들어, 30이라면 5를 6개 쓰는 것이, 3을 10개 쓰는것 보다 낫다.

1. 위에 썼듯, 5를 최대한 많이 사용하기 위해서 먼저, N이 5로 나누어 지는지 확인한 후,  나누어 진다면 answer에 N을 5로 나눈 몫을 더한 후 반환한다.

2. N이 5로 나누어지지 않는 경우에는, N에서 3을 빼준 후, answer 에 1을 더한다(3을 한번 사용).

3. N이 0이 될때까지 1~2 과정을 반복하되, N이 음수가 되는 경우에는 N이 5와 3만으로 표현되지 않는 것이므로 -1을 반환한다.

 

Python Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
n=int(input())
answer = 0
while n != 0:
    if n%5==0:
        answer+=n//5
        print(answer)
        break
    else :
        n-=3
        answer+=1
        if n==0:
            print(answer)
            break
    if n<0 :
        print(-1)
        break
cs

 

 

반응형

'알고리즘 > 백준' 카테고리의 다른 글

백준 2579 계단 오르기  (0) 2020.02.27
백준 4949 균형잡힌 세상  (0) 2020.02.25
백준 11052 카드 구매하기  (0) 2020.02.24
백준 7576 토마토  (0) 2020.02.21
백준 15998 카카오머니  (0) 2020.02.20
반응형

유형 : dp

 

카드 n장을 살 때, 지불할 수 있는 최대 금액을 구하는 문제이다.

 

풀이과정

 카드 i 장을 구매하는데 필요한 금액을 dp[i] 이고, 카드 n장이 들어있는 팩의 가격이 p[n]라 하면, dp[i]는 아래와 같다.

 dp[i] = dp[i-n] + p[n]

 가능한 모든 n에 대하여 dp[i]가 최대값이 되도록 update해나가면 된다.

Python Code

1
2
3
4
5
6
7
v=int(input())
p=list(map(int,input().split()))
dp = [0]
 
for n in range(1,v+1):
    dp.append(max(dp[-i-1]+p[i] for i in range(n)))
print(dp)
cs

 

 

반응형

'알고리즘 > 백준' 카테고리의 다른 글

백준 4949 균형잡힌 세상  (0) 2020.02.25
백준 2839 설탕배달  (0) 2020.02.24
백준 7576 토마토  (0) 2020.02.21
백준 15998 카카오머니  (0) 2020.02.20
백준 1931 회의실 배정  (0) 2020.02.17
반응형

유형 : bfs

풀이과정

1. ripen을 deque로 선언한 후, 토마토들의 정보를 읽으며 익은 토마토의 인덱스 (i,j)를 넣는다.

2. ripen에서 popleft로 하나씩 꺼내가며, 토마토의 이웃을 체크하고 익지 않은 토마토가 있으면 상태를 1로 바꾸어주고 ripen에 넣는다. 이때, time step을 세기위해, 각 time step마다, ripen에서 꺼내기 전에, ripen에 몇개의 요소가 들어있는지 체크해두고 popleft로 체크된 수 만큼만 빼고, 새로 넣는 토마토는 오른쪽으로 넣는다.

3. ripen이 빌때까지 2를 반복한 후, 장애물의 숫자와 익은 토마토의 숫자의 합이 m*m 일 경우에는 시간을, 아닐경우에는 -1을 반환한다.

 

Python Code

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
import collections
import sys
 
m,n = map(int,sys.stdin.readline().split())
row = 0
tomato = []
ripen=collections.deque()
obstacle_num =0
ripen_num=0
for i in range(n):
    temp = list(map(int,sys.stdin.readline().split()))
    for j in range(m):
        if temp[j]==1:
            ripen.append([row+1,j+1])
            ripen_num +=1
        elif temp[j] == -1:
            obstacle_num+=1
    temp.insert(0,-1)
    temp.append(-1)
    tomato.append(temp)
    row+=1
 
tomato.insert(0, [-1 for i in range(m+2)])
tomato.append([-1 for i in range(m+2)])
 
answer = -1
while len(ripen) != 0:
    answer+=1
    _num = len(ripen)
    for i in range(_num):
        t = ripen.popleft()
        #print(t)
        if tomato[t[0]+1][t[1]]==0:
            ripen.append([t[0]+1,t[1]])
            tomato[t[0]+1][t[1]]=1
            ripen_num+=1
        if tomato[t[0]-1][t[1]]==0:
            ripen.append([t[0]-1,t[1]])
            tomato[t[0]-1][t[1]]=1
            ripen_num+=1
        if tomato[t[0]][t[1]+1]==0:
            ripen.append([t[0],t[1]+1])
            tomato[t[0]][t[1]+1]=1
            ripen_num+=1
        if tomato[t[0]][t[1]-1]==0:
            ripen.append([t[0],t[1]-1])
            tomato[t[0]][t[1]-1]=1
            ripen_num+=1
if ripen_num+obstacle_num == n*m:
    print(answer)
else:
    print(-1)
cs

* 편의를 위해서 tomato는 (m+2)*(m+2) 행렬로, 가장자리를 -1(장애물)로 채웠습니다.

 

문제풀기

 

7576번: 토마토

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N이 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M,N ≤ 1,000 이다. 둘째 줄부터는 하나의 상자에 저장된 토마토들의 정보가 주어진다. 즉, 둘째 줄부터 N개의 줄에는 상자에 담긴 토마토의 정보가 주어진다. 하나의 줄에는 상자 가로줄에 들어있는 토마토의 상태가 M개의 정수로 주어진다. 정수 1은 익은 토마토, 정수 0은 익지 않은 토마토, 정수 -1은 토마

www.acmicpc.net

 

반응형

'알고리즘 > 백준' 카테고리의 다른 글

백준 2839 설탕배달  (0) 2020.02.24
백준 11052 카드 구매하기  (0) 2020.02.24
백준 15998 카카오머니  (0) 2020.02.20
백준 1931 회의실 배정  (0) 2020.02.17
11053 가장 긴 증가하는 부분 수열  (0) 2020.02.14
반응형

카카오 코드 페스티벌 2018 본선 문제

 

 입출금 로그를 보고 잘못된 부분이 있는지, 없다면 최소 충전금액은 얼마인지 알아내는 문제이다.

 

풀이과정

 먼저, a, b를 list로 가지고 있을 필요없이 입력받고 바로바로 처리하면 효율적으로 문제를 해결할 수 있다.

 minB는 0이 아닌 b의 최솟값이며, lastB는 이전 step의 b값이 된다.

 a+lastB가 음수인 경우에는 충전이 필요하며 충전 금액 temp는 아래와 같이 주어진다.

 temp = b - a - lastB

 충전금액은 최소충전금액의 배수만 가능하므로, 최소충전금액(변수 pay)은 충전액들의 최소 공배수가 되고, 이를 해결하기 위해 pay 변수를 계속해서 pay변수와 위의 temp 변수의 최대공약수로 갱신해준다.

 

 로그가 잘못 되었을 조건은 아래와 같다.

 1. 각 step에서 잔액 b는 전 step에서의 잔액과 현 step에서의 입출금 a의 합으로 주어져야하는데, b = lastB + a 를 만족하지 않으면 그 로그는 잘못된 로그이다.

 2. 최소충전금액이 pay이므로, 입출금 후의 잔액의 최솟값 minB는 pay보다 작아질 수 없다. 따라서 minB < pay 인 경우 그 로그는 잘못된 로그이다.

 

Python Code

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
import sys
 
def gcd(a, b):
  while (b != 0):
    temp = a % b
    a = b
    b = temp
  return abs(a)
 
= int(input())
minB = pow(10,18)
last_b = 0
pay = None
 
valid = True
for i in range(n):
    a,b = map(int,sys.stdin.readline().split())
    if a+lastB<0:
        temp = b-a-lastB
        if b != 0 and b<minB : minB=b
        if pay == None:
            pay = temp
        else :
            pay = gcd(pay,temp)
            if pay <= minB and minB != pow(10,18):
                valid = False
                break
    else:
        if lastB + a != b:
            valid = False
            break
    lastB = b
if valid and pay != None : print(pay)
elif valid and pay == None : print(1)
else : print(-1)
cs

 

문제풀기

 

15998번: 카카오머니

만약 유효한 최소 충전 단위 M(1 ≤ M ≤ 9 * 1018)이 존재한다면, 첫 번째 줄에 M 을 출력한다. 가능한 값이 여러 가지 있다면, 그중 9 * 1018 이하인 것을 아무거나 하나 출력한다. 존재하지 않는다면 -1을 출력한다.

www.acmicpc.net

 

반응형

'알고리즘 > 백준' 카테고리의 다른 글

백준 2839 설탕배달  (0) 2020.02.24
백준 11052 카드 구매하기  (0) 2020.02.24
백준 7576 토마토  (0) 2020.02.21
백준 1931 회의실 배정  (0) 2020.02.17
11053 가장 긴 증가하는 부분 수열  (0) 2020.02.14
반응형

유형 : 그리디

 

빨리 끝나는 회의부터 처리해야 한다. 이때, 끝나는 시간이 똑같은 회의의 경우, 시작 시간이 빠른 회의부터 처리한다.

 

코드

import sys

n=int(sys.stdin.readline())
times = []
for _ in range(n):
    times.append(tuple(map(int,sys.stdin.readline().split())))
  
times.sort()
times.sort(key=lambda x: x[1])
now,ans=0,0
for time in times:
    if time[0]>=now:
        ans+=1
        now=time[1]
print(ans)

 

정렬

 위의 코드에서는 times.sort()로 회의 시작 시간을 기준으로 정렬을 한 후, 회의 종료 시간을 기준으로 한번 더 정렬을 함으로써 위에서 언급한 규칙을 만족시켰다.

 하지만, 아래와 같이 comparator를 직접 정의함으로써 한번에 정렬할 수도 있는데, 내장함수로 두번 정렬하는 위의 방법이 훨씬 효율적이었다. ( 위의 방법 : 메모리 44944kb, 시간 328ms, 아래의 방법 : 메모리 50360kb, 시간 552ms)

from functools import cmp_to_key

def compare(x, y):
    if x[1] < y[1] :
        return -1 
    elif x[1] > y[1] :
        return 1
    else: 
        if x[0] < y[0] :
            return -1
        else:
            return 1
times.sort(key=cmp_to_key(compare))

 

문제풀기

https://www.acmicpc.net/problem/1931

반응형

'알고리즘 > 백준' 카테고리의 다른 글

백준 2839 설탕배달  (0) 2020.02.24
백준 11052 카드 구매하기  (0) 2020.02.24
백준 7576 토마토  (0) 2020.02.21
백준 15998 카카오머니  (0) 2020.02.20
11053 가장 긴 증가하는 부분 수열  (0) 2020.02.14

+ Recent posts