728x90
반응형

문제:

풀이방법:

진행되는 단계를 보면 재귀적으로 수행한다고 했으므로 재귀로 구성하는 것이 맞다.

전체적인 진행은 make라는 함수에서 된다. 

1, 2는 split()이라는 함수에서 진행된다. 2는 균형잡힌 문자열으로만 분리하면 되므로 ( 면 +1을 ) 면- 1을 해서 균형잡힌 문자열으로 분리를 한다.

 이렇게 분리를 한 뒤에 u가 올바른 괄호 문자열인지 확인해야 한다.(3) 이 작업은 check라는 함수에서 진행된다. split과 비슷하게 작동을 하지만 count가 음수로 내려간다면 올바른 괄호 문자열이 아니기 때문에 이 경우에 False를 반환하고 나머지는 True를 반환하도록 한다. 그리고 이를 문자열에 붙이고 v에 대해서 1을 다시 진행하도록 make(v)를 수행한다.만약 u가 올바른 괄호 문자열이 아니라면 수행하라는 작업을 그대로 수행하면 된다.

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
def split(p):
    if p=='':
        return ''
    else:
        count=0
        for i,k in enumerate(p):
            if k==')':
                count-=1
            else:
                count+=1
            if count==0:
                break
        return p[:i+1],p[i+1:]
def check(u):
    count=0
    for i in u:
        if i=='(':
            count+=1
        else:
            count-=1
        if count < 0:
            return False
    return True
 
def make(p):
    try:
        u,v=split(p)
    except:
        return ''
    answer=''
    if check(u):
        answer+=u
        answer+=make(v)
        return answer
    else:
        answer+='('
        answer+=make(v)
        answer+=')'
        u=u[1:-1]
        for i in u:
            if i=='(':
                answer+=')'
            else:
                answer+='('
        return answer
def solution(p):
    answer=make(p)
    return answer
cs

문제링크:

https://programmers.co.kr/learn/courses/30/lessons/60058

 

코딩테스트 연습 - 괄호 변환 | 프로그래머스

카카오에 신입 개발자로 입사한 콘은 선배 개발자로부터 개발역량 강화를 위해 다른 개발자가 작성한 소스 코드를 분석하여 문제점을 발견하고 수정하라는 업무 과제를 받았습니다. 소스를 컴파일하여 로그를 보니 대부분 소스 코드 내 작성된 괄호가 개수는 맞지만 짝이 맞지 않은 형태로 작성되어 오류가 나는 것을 알게 되었습니다. 수정해야 할 소스 파일이 너무 많아서 고민하던 콘은 소스 코드에 작성된 모든 괄호를 뽑아서 올바른 순서대로 배치된 괄호 문자열을 알려주는

programmers.co.kr

 

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[Programmers]2018 Kakao.압축  (0) 2019.12.02
[Programmers]2018 Kakao.방금그곡  (0) 2019.12.01
[Programmers]2020 Kakao. 문자열 압축  (0) 2019.11.14
[BOJ]2358. 평행선  (0) 2019.11.13
[BOJ]GIT- 정리  (0) 2019.11.12
728x90
반응형

문제:

풀이방법:

 처음에는 스택으로 구축할까 생각하다가 많이 복잡할 것 같아서 슬라이싱을 활용한 문자열 비교로 해결하기로 하였다. 

문자열의 길이가 1이면 항상 답은 1이라는 예외처리로 시작한다. 몇 개 단위로 자르는 것이 가장 짧은 방법인지 알지 못하므로 1부터 len(s)까지 분할 하도록 한다. i개의 단어로 자르면서 앞과 현재가 같다면 count를 하나올려주도록 한다. 만약 다르다면 count를 비교해보도록 한다. count가 1이라면 그냥 문자열에 더하고, 1이 아니라면 숫자를 같이 더해주도록 한다.

 이렇게 각 길이의 단위로 자른 문자열을 모두 담았다면 가장 작은 값을 반환하도록 한다.

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
def solution(s):
    answers=[]
    if len(s)==1:
        return 1
    for i in range(1,len(s)):
        answer = ''
        count = 1
        for j in range(i,len(s),i):
            if s[j-i:j]==s[j:j+i]:
                count+=1
            else:
                if count==1:
                    answer+=s[j-i:j]
                else:
                    answer+=str(count)+s[j-i:j]
                    count=1
        if len(s[j:j+i])==i:
            if count==1:
                answer+=s[j-i:j]
            else:
                answer+=str(count)+s[j-i:j]
                count=1
        else:
            answer+=s[j:j+i]
        answers.append(len(answer))
    return min(answers)
cs

 

문제링크:

https://programmers.co.kr/learn/courses/30/lessons/60057

 

코딩테스트 연습 - 문자열 압축 | 프로그래머스

데이터 처리 전문가가 되고 싶은 어피치는 문자열을 압축하는 방법에 대해 공부를 하고 있습니다. 최근에 대량의 데이터 처리를 위한 간단한 비손실 압축 방법에 대해 공부를 하고 있는데, 문자열에서 같은 값이 연속해서 나타나는 것을 그 문자의 개수와 반복되는 값으로 표현하여 더 짧은 문자열로 줄여서 표현하는 알고리즘을 공부하고 있습니다. 간단한 예로 aabbaccc의 경우 2a2ba3c(문자가 반복되지 않아 한번만 나타난 경우 1은 생략함)와 같이 표현할 수

programmers.co.kr

 

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[Programmers]2018 Kakao.방금그곡  (0) 2019.12.01
[Programmers]2020 Kakao.괄호 변환  (0) 2019.11.15
[BOJ]2358. 평행선  (0) 2019.11.13
[BOJ]GIT- 정리  (0) 2019.11.12
[BOJ]1937. 욕심쟁이 판다  (0) 2019.11.11
728x90
반응형

문제:

평면상에 n개의 점이 있다. 이 점들 중에 서로 다른 두 점을 선택하면 하나의 직선이 만들어진다. 이와 같이 직선을 만들었을 때, x축 또는 y축에 평행한 직선이 몇 개나 되는지 알아내는 프로그램을 작성하시오.

입력:

첫째 줄에 n(1<=n<=100,000)이 주어진다. 다음 n개의 줄에는 각 점의 좌표가 int 범위에서 주어진다. 만약 입력에 서로 같은 두 점이 주어지면, 그 두 점을 이용하여 직선을 만들 수 있다.

출력:

첫째 줄에 답을 출력한다.

풀이방법:

 x좌표가 일치하는 두 점들이나 y좌표가 일치하는 두 점들이 축과 평행을 이루기 때문에 정렬을 통해서 쉽게 찾을 수 있을 것 같았다. 하지만 문제 이해를 잘못해서 처음에 조금 헤매었고, 질문에 있는 글을 보면서 겨우 이해했다.

 '만약 입력에 서로 같은 두 점이 주어지면, 그 두점을 이용하여 직선을 만들 수 있다.' 라는 문구때문에 많이 헷갈렸다. 처음에는 (0,0)_1 (0,0)_2 (0,10) 이렇게 있으면 (0,0)_1, (0,0)_2을 (0,0)_1, (0,10)을 (0,0)_2, (0,10)을 연결할 수 있어서 3개라고 생각했지만 아니였다.

 문제에서 원하는 것은 위와 같은 경우에는 (0,0)_1 (0,0)_2의 두 점을 통해 x=0, y=0이라는 두 직선을 만들 수 있었고, (0,0)_1, (0,10)을 (0,0)_2, (0,10) 이것들은 x=0인 직선에 포함되는 것이므로 카운트를 하지 않는다는 것이였다. 그래서 답은 2가 되는 것이였다.

 그래서 x축과 평행하게 만들 수 있는 직선의 숫자값, y축과 평행하게 만들 수 있는 직선의 숫자값을 각각 담는 배열을 만들어서 그 길이를 더하도록 했다.

하지만 매우 비효율적으로 구성했기 때문에 시간초과가 발생하였고 PyPy3로 통과할 수 있었다.

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
points=[]
answer=0
n=int(input())
for _ in range(n):
    point=tuple(map(int,input().split()))
    points.append(point)
    
points=sorted(points)
xs=[]
for i in range(len(points)):
    for j in range(i+1,len(points)):
        if points[i][0]==points[j][0]:
            if not points[i][0in xs:
                xs.append(points[i][0])
                answer+=1
            break
        else:
            break
        
ys=[]
points=sorted(points,key=lambda x:x[1])
for i in range(len(points)):
    for j in range(i+1,len(points)):
        if points[i][1]==points[j][1]:
            if not points[i][1in ys:
                ys.append(points[i][1])
                answer+=1
            break
        else:
            break
print(answer)
cs

문제링크:

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

 

2358번: 평행선

첫째 줄에 n(1≤n≤100,000)이 주어진다. 다음 n개의 줄에는 각 점의 좌표가 int 범위에서 주어진다. 만약 입력에 서로 같은 두 점이 주어지면, 그 두 점을 이용하여 직선을 만들 수 있다.

www.acmicpc.net

 

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[Programmers]2020 Kakao.괄호 변환  (0) 2019.11.15
[Programmers]2020 Kakao. 문자열 압축  (0) 2019.11.14
[BOJ]GIT- 정리  (0) 2019.11.12
[BOJ]1937. 욕심쟁이 판다  (0) 2019.11.11
[BOJ]6359. 만취한 상범  (0) 2019.11.09
728x90
반응형

지금까지 풀었던 문제들을 GIT에 정리하기 시작했다. 많은 양이라 한 번에 다 업로드 하지는 못하고 있지만 차근차근 하나씩 다 올릴 예정이다. 문제는 1000번 단위로 정리하고 있으며 업로드 되어 있는 목록은 다음과 같다.

[2019-11-12] 현재는 1000~2999번까지 업로드

  • 1000~2000

    • 1002 터렛
    • 1003 피보나치 함수
    • 1009 분산처리
    • 1011 Fly me to the Alpha Centauri
    • 1015 수열 정렬
    • 1016 제곱 ㄴㄴ수
    • 1018 체스판 다시 칠하기
    • 1037 약수
    • 1049 기타줄
    • 1065 한수
    • 1075 나누기
    • 1076 저항
    • 1080 행렬
    • 1110 더하기 사이클
    • 1120 문자열
    • 1149 RGB거리
    • 1152 단어의 개수
    • 1157 단어 공부
    • 1159 농구 경기
    • 1181 단어 정렬
    • 1260 DFS와 BFS
    • 1309 동물원
    • 1325 효율적인 해킹
    • 1357 뒤집힌 덧셈
    • 1371 가장 많은 글자
    • 1373 2진수 8진수
    • 1389 케빈 베이컨의 6단계 법칙
    • 1406 에디터
    • 1436 영화감독 숌
    • 1475 방번호
    • 1476 날짜 계산
    • 1495 기타리스트
    • 1547 공
    • 1561 놀이공원
    • 1629 곱셈
    • 1654 랜선 자르기
    • 1655 가운데를 말해요
    • 1676 팩토리얼 0의 개수
    • 1697 숨바꼭질
    • 1699 제곱수의 합
    • 1712 손익분기점
    • 1744 수 묶기
    • 1759 암호 만들기
    • 1789 수들의 합
    • 1834 나머지와 몫이 같은 수
    • 1874 스택 수열
    • 1890 점프
    • 1904 01타일
    • 1912 연속합
    • 1920 수 찾기
    • 1927 최소힙
    • 1929 소수 구하기
    • 1931 회의실 배정
    • 1977 완전 제곱수
    • 1987 알파벳
  • 2001~3000

    • 2004 조합 0의 개수
    • 2011 암호코드
    • 2022 사다리
    • 2075 N번째 큰 수
    • 2133 타일 채우기
    • 2156 포도주 시식
    • 2163 초콜릿 자르기
    • 2178 미로찾기
    • 2193 이친수
    • 2217 로프
    • 2225 합분해
    • 2231 분해합
    • 2292 벌집
    • 2309 일곱 난쟁이
    • 2312 수 복원하기
    • 2331 반복 수열
    • 2407 조합
    • 2504 괄호의 값
    • 2606 바이러스
    • 2667 단지번호 붙이기
    • 2775 부녀회장이 될테야
    • 2805 나무 자르기
    • 2839 설탕 배달
    • 2851 슈퍼 마리오
    • 2869 달팽이는 올라가고 싶다.
    • 2875 대회 or 인턴
    • 2941 크로아티아 알파벳
    • 2960 에라토스테네스의 체
  • 3001~4000

    • 3036 링
    • 3053 택시 기하학
  • 4001~5000

    • 4307 개미
    • 4344 평균은 넘겠지
    • 4948 베르트랑 공준
    • 4949 균형잡힌 세상
  • 5001~6000

    • 5430 AC
    • 5567 결혼식
  • 6001~7000

    • 6064 카잉 달력
    • 6591 이항 쇼다운
  • 7001~8000

    • 7568 덩치
    • 7576 토마토
    • 7569 토마토
  • 8001~9000

    • 8979 올림픽
  • 9001~10000

    • 9012 괄호
    • 9095 1,2,3 더하기
    • 9461 파도반 수열
    • 9465 스티커
    • 9613 GCD 합
    • 9933 민균이의 비밀번호
    • 9935 문자열 폭발
  • 10001~11000

    • 10250 ACM 호텔
    • 10253 헨리
    • 10451 순열 사이클
    • 10610 30
    • 10816 숫자 카드2
    • 10825 국영수
    • 10828 스택
    • 10844 쉬운 계단 수
  • 11001~

    • 11047 동전0
    • 11050 이항계수1
    • 11051 이항계수2
    • 11053 가장 긴 증가하는 부분 수열
    • 11057 오르막 수
    • 11052 카드 구매하기
    • 11279 최대힙
    • 11286 절대값 힙
    • 11718 그래도 출력하기
    • 11816 조세퍼스 문제0
    • 14501 퇴사
    • 14889 스타트와 링크
    • 15649 N과 M
    • 17144 미세먼지 안녕!

https://github.com/kimkyeonghun/BOJ

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[Programmers]2020 Kakao. 문자열 압축  (0) 2019.11.14
[BOJ]2358. 평행선  (0) 2019.11.13
[BOJ]1937. 욕심쟁이 판다  (0) 2019.11.11
[BOJ]6359. 만취한 상범  (0) 2019.11.09
[BOJ]1965. 상자넣기  (0) 2019.11.08
728x90
반응형

문제:

n*n의 크기의 대나무 숲이 있다. 욕심쟁이 판다는 어떤 지역에서 대나무를 먹기 시작한다. 그리고 그 곳의 대나무를 다 먹어 치우면 상, 하, 좌, 우 중 한 곳으로 이동을 한다. 그리고 또 그곳에서 대나무를 먹는다. 그런데 단 조건이 있다. 이 판다는 매우 욕심이 많아서 대나무를 먹고 자리를 옮기면 그 옮긴 지역에 그 전 지역보다 대나무가 많이 있어야 한다. 만약에 그런 지점이 없으면 이 판다는 불만을 가지고 단식 투쟁을 하다가 죽게 된다.(-_-)

이 판다의 사육사는 이런 판다를 대나무 숲에 풀어 놓아야 하는데, 어떤 지점에 처음에 풀어 놓아야 하고, 어떤 곳으로 이동을 시켜야 둘 다 소중한 생명이지만 판다가 최대한 오래 살 수 있는지 고민에 빠져 잇따. 우리의 임무는 이 사육사를 도와주는 것이다. n*n 크기의 대나무 숲이 주어져 있을 때, 이 판다가 최대한 오래 살려면 어떤 경로를 통하여 움직여야 하는지 구하여라.

입력:

첫째 줄에 대나무 숲의 크기 n(1<=n<=500)이 주어진다. 그리고 둘째 줄부터 n+1번째 줄까지 대나무 숲의 정보가 주어진다. 대나무 숲의 정보는 공백을 사이로 두고 각 지역의 대나무의 양이 정수 값으로 주어진다. 대나무의 양은 1,000,000보다 작거나 같은 자연수이다.

출력:

첫째 줄에는 판다가 최대한 살 수 있는 일수(K)를 출력한다.

풀이방법:

 기본적으로는 dfs를 사용해서 판다의 이동 경로를 알아야 하지만 문제에서 원하는 것은 판다가 최대한 살 수 있는 일수, 즉 최대로 이동 가능한 거리의 길이를 원하고 있다. 작은 크기의 경우에는 시작점을 달리 해서 최대 일수를 찾을 수 있지만 500 x 500의 경우에는 이 것을 다 탐색하기에는 많은 시간이 걸릴 것이다.

 따라서 이를 해결하기 위해서 다이나믹 프로그래밍에서 메모리제이션을 사용한다. 한 점에서 출발을 해서 움직이다가 이미 이전에 다른 곳에서 움직였던 기록이 남아있고 그것을 기록해뒀다면 더 이상 그 길로 이동할 필요없이 그 값을 참조해서 다시 돌아오면 된다. 따라서 dfs로 이동을 하지만 이전에 이 길을 지나간 기록이 있다면 그 값을 가져오고, 그렇지 않다면 더 들어가면서 값을 기록하도록 한다.

 또한 재귀적으로 함수를 구현했기 때문에 깊은 재귀로 인한 에러를 방지하기 위해서 sys.setrecursionlimit를 사용한다.

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
import sys
sys.setrecursionlimit(1000000)
 
def dfs(x,y):
    global answer
    
    if dp[x][y] != 0:
        return dp[x][y]
 
    dp[x][y] = 1
    for i in range(4):
        nx = x+dx[i]
        ny = y+dy[i]
        if 0 <= nx< n and 0 <= ny< n:
            if trees[nx][ny] > trees[x][y]:
                dp[x][y] = max(dp[x][y], dfs(nx, ny)+1)
    return dp[x][y]
 
dx = [001-1]
dy = [1-100]
= int(input())
trees = []
for _ in range(n):
    trees.append(list(map(int, input().split())))
 
answer = 0
visited = [[0 for _ in range(n) ] for _ in range(n)]
dp = [[0 for _ in range(n) ] for _ in range(n)]
 
for i in range(n):
    for j in range(n):
        answer = max(dfs(i,j),answer)
print(answer)
cs

문제링크:

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

 

1937번: 욕심쟁이 판다

n*n의 크기의 대나무 숲이 있다. 욕심쟁이 판다는 어떤 지역에서 대나무를 먹기 시작한다. 그리고 그 곳의 대나무를 다 먹어 치우면 상, 하, 좌, 우 중 한 곳으로 이동을 한다. 그리고 또 그곳에서 대나무를 먹는다. 그런데 단 조건이 있다. 이 판다는 매우 욕심이 많아서 대나무를 먹고 자리를 옮기면 그 옮긴 지역에 그 전 지역보다 대나무가 많이 있어야 한다. 만약에 그런 지점이 없으면 이 판다는 불만을 가지고 단식 투쟁을 하다가 죽게 된다(-_-) 이

www.acmicpc.net

 

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[BOJ]2358. 평행선  (0) 2019.11.13
[BOJ]GIT- 정리  (0) 2019.11.12
[BOJ]6359. 만취한 상범  (0) 2019.11.09
[BOJ]1965. 상자넣기  (0) 2019.11.08
[BOJ]2225. 합분해  (0) 2019.11.07
728x90
반응형

문제:

서강대학교 곤자가 기숙사의 지하에는 n개의 방이 일렬로 늘어선 감옥이 있다. 각 방에는 벌점을 많이 받는 학생이 구금되어있다.

그러던 어느 날, 감옥 간수인 상범이는 지루한 나머지 정신나간 게임을 하기로 결정했다. 게임의 첫 번째 라운드에서 상범이는 위스키를 한 잔 들이키고, 달려가며 감옥을 한 개씩 모두 연다. 그 다음 라운드에서는 2,4,6, ... 번 방을 다시 잠그고, 세 번째 라운드에서는 3, 6, 9, ... 번 방이 열려있으면 잠그고, 잠겨있으면 연다. k번째 라운드에서는 번호가 k인 배수인 방이 열려 있으면 잠그고, 잠겨 있으면 연다. 이렇게 n번째 라운드까지 진행한 이후, 상범이는 위스키의 마지막 병을 마시고 쓰러져 잠든다.

입력:

입력의 첫 번째 줄에는 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄에 한 개씩 방의 개수 n(5<=n<=100)이 주어진다.

출력:

한 줄에 한 개씩 각 테스트 케이스의 답, 즉 몇 명이 탈출할 수 있는지를 출력한다.

 

풀이방법:

다이나믹 프로그래밍으로 풀어야 한다고 하는데 방의 개수가 100으로 작은편이기 때문에 완전탐색을 사용해서 풀었다.

0이면 열려 있고, 1이면 닫혀 있다고 했을 때, 해당하는 숫자 j의 배수마다 0이면 1로, 1이면 0으로 바꾸도록 했다. 이렇게 모두 탐색을 완료하면 0의 갯수에서 하나를 빼서 답을 구한다.

(다 풀고나니 1을 열려 있고, 0을 닫혀 있다 가정하고, 마지막에 sum을 하는 것이 더 깔끔할 것 같다.)

1
2
3
4
5
6
7
8
9
10
11
T=int(input())
for i in range(T):
    n=int(input())
    answer=[0]*(n+1)
    for j in range(2,n+1):
        for k in range(j,n+1,j):
            if answer[k]==0:
                answer[k]=1
            else:
                answer[k]=0
    print(answer.count(0)-1)
cs

문제링크:

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

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[BOJ]GIT- 정리  (0) 2019.11.12
[BOJ]1937. 욕심쟁이 판다  (0) 2019.11.11
[BOJ]1965. 상자넣기  (0) 2019.11.08
[BOJ]2225. 합분해  (0) 2019.11.07
[BOJ]1010. 다리 놓기  (0) 2019.11.06
728x90
반응형

문제:

정육면체 모양의 상자가 일렬로 늘어서 있다. 상자마다 크기가 주어져 있는데, 앞에 있는 상자의 크기가 뒤에 있는 상자의 크기보다 작으면, 앞에 있는 상자를 뒤에 있는 상자 안에 넣을 수 있다. 예를 들어 앞에서부터 순서대로 크기가(1,5,2,3,7)인 5개의 상자가 있다면, 크기 1인 상자를 크기 5인 상자에 넣고, 다시 이 상자를 크기 7인 상자 안에 넣을 수 있다. 하지만 이렇게 상자를 넣을 수 있는 방법을 여러 가지가 있을 수 있다. 앞의 예에서 차례대로 크기가 1, 2, 3, 7인 상자를 선택하면 총 4개의 상자가 한 개의 상자에 들어가게 된다.

 

상자의 크기가 주어질 때, 한 번에 넣을 수 있는 최대의 상자 개수를 출력하는 프로그램을 작성하시오.

입력:

파일의 첫 번째 줄은 상자의 개수 n(1<=n<=1000)을 나타낸다. 두 번째 줄에는 각 상자의 크기가 순서대로 주어진다. 상자의 크기는 1,000을 넘지 않는 자연수이다.

출력:

첫쨰 줄에 한 줄에 넣을 수 있는 최대의 상자 개수를 출력한다.

풀이방법:

앞에 있는 작은 상자를 뒤에 있는 큰 상자에 넣을 수 있으므로 이는 다이나믹프로그래밍을 사용한 LIS 문제와 같다.

LIS에서 lis[i]는 i번째 수열까지 한 번에 넣을 수 있는 최대의 상자 개수이며, i+1을 추가했을 때, boxes[1]~boxes[i]까지 boxes[i+1]보다 작은 값이 있는지 파악하고, 그 수에 해당하는 lis[k] 값들 중에 최댓값에 1을 더해주는 방식으로 진행한다. 그러고 전체 lis에서 최댓값을 출력해주면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
n=int(input())
boxes=list(map(int,input().split()))
 
lis=[1]*n
for i in range(1,n):
    temp = (-1,-1)
    for j in range(i+1):
        if boxes[j] < boxes[i]:
            if temp[0< lis[j]:
                temp = (lis[j],j)
    if temp[1>= 0:
        lis[i]=lis[temp[1]]+1
print(max(lis))
cs

문제링크:

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

 

1965번: 상자넣기

정육면체 모양의 상자가 일렬로 늘어서 있다. 상자마다 크기가 주어져 있는데, 앞에 있는 상자의 크기가 뒤에 있는 상자의 크기보다 작으면, 앞에 있는 상자를 뒤에 있는 상자 안에 넣을 수가 있다. 예를 들어 앞에서부터 순서대로 크기가 (1, 5, 2, 3, 7)인 5개의 상자가 있다면, 크기 1인 상자를 크기 5인 상자에 넣고, 다시 이 상자를 크기 7인 상자 안에 넣을 수 있다. 하지만 이렇게 상자를 넣을 수 있는 방법은 여러 가지가 있을 수 있다. 앞의

www.acmicpc.net

 

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[BOJ]1937. 욕심쟁이 판다  (0) 2019.11.11
[BOJ]6359. 만취한 상범  (0) 2019.11.09
[BOJ]2225. 합분해  (0) 2019.11.07
[BOJ]1010. 다리 놓기  (0) 2019.11.06
[BOJ]1495. 기타리스트  (0) 2019.11.05
728x90
반응형

문제:

0부터 N까지의 정수 K개를 더해서 그 합이 N이 되는 경우의 수를 구하는 프로그램을 작성하시오.

 

덧셈의 순서가 바뀐 경우는 다른 경우로 센다(1+2와 2+1은 서로 다른 경우) 또한 한 개의 수를 여러 번 쓸 수도 있다.

입력:

첫째 줄에 두 정수 N(1<=N<=200),K(1<=K<=200)가 주어진다.

출력:

첫째 줄에 답을 1,000,000,000으로 나눈 나머지를 출력한다.

풀이방법:

동적계획법을 사용해서 이 문제를 풀었다. 점화식은 간단하다. K개의 합이 N이 되었을 때, 맨 마지막 수( l )를 빼면 남은 수는 K-1개로 N-l 이 남는 다는 것이다. 그래서 dp 테이블을 다음과 같이 구성할 수 있다.

dp[ i ][ j ] 는 i개의 수를 가지고 합이 j가 되는 경우를 뜻한다. 따라서 처음에는 1로 초기화되며, 한 층이 지날때마다 경우의 수가 더해져 우리가 원하는 dp[k][n]을 구할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
n,k = map(int,input().split())
dp=[[0 for _ in range(n+1)]for _ in range(k+1)]
mod=1000000000
for i in range(n+1):
    dp[1][i]=1
 
for i in range(2,k+1):
    for j in range(n+1):
        for l in range(j+1):
            dp[i][j]+=dp[i-1][l]
        dp[k][n]%=mod
    
print(dp[k][n])
cs

문제링크:

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

 

2225번: 합분해

첫째 줄에 답을 1,000,000,000으로 나눈 나머지를 출력한다.

www.acmicpc.net

 

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[BOJ]6359. 만취한 상범  (0) 2019.11.09
[BOJ]1965. 상자넣기  (0) 2019.11.08
[BOJ]1010. 다리 놓기  (0) 2019.11.06
[BOJ]1495. 기타리스트  (0) 2019.11.05
[BOJ]14848. 정수 게임  (0) 2019.11.04
728x90
반응형

문제:

재원이는 한 도시의 시장이 되었다. 이 도시에는 도시를 동쪽과 서쪽으로 나누는 큰 강이 흐르고 있다. 하지만 재원이는 다리가 없어서 시민들이 강을 건너는데 큰 불편을 겪고 있음을 알고 다리는 짓기로 결심하였다. 강 주변에서 다리를 짓기에 적합한 곳을 사이트라고 한다. 재원이는 강 주변을 면밀히 조사해 본 결과 강의 서쪽에는 N개의 사이트가 있고 동쪽에는 M개의 사이트가 있다는 것을 알았다. (N<=M)

 

재원이는 서쪽의 사이트와 동쪽의 사이트를 다리로 연결하려고 한다. (이때 한 사이트에는 최대 한 개의 다리만 연결될 수 있다.) 재원이는 다리를 최대한 많이 지으려고 하기 때문에 서쪽의 사이트 개수만큼 (N개) 다리를 지으려고 한다. 다리끼리는 서로 겹쳐질 수 없다고 할 때 다리를 지을 수 있는 경우의 수를 구하는 프로그램을 작성하라.

 

입력:

입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다 그 다음 줄부터 각각의 테스트케이스에 대해 강의 서쪽과 동쪽에 있는 사이트의 개수 정수 N,M(0<N<=M<30)이 주어진다.

출력:

각 테스트 케이스에 대해 주어진 조건하에 다리를 지을 수 있는 경우의 수를 출력한다.

풀이방법:

이 문제는 다이나믹 프로그래밍을 활용해서 풀 수 있는 문제이다. 

왼쪽에 3개의 사이트가 있고, 오른쪽에 5개의 사이트가 있다고 가정하자. 그럼 왼쪽의 3개와 오른쪽의 5개를 이어야 하는 문제가 된다. 하지만 왼쪽의 제일 위 점과 오른쪽의 제일 위 점에 다리를 건설했다고 하자.

맨 위 점을 이음

이제는 아래 남은 점들은 왼쪽의 2개의 점, 오른쪽의 4개의 점을 이어야 하는 문제가 된다. 이 단계에서 한 번 더 진행하면 이제 왼쪽에는 한 개만 남고 오른쪽에는 3개, 2개 ... 가 남게 된다. 왼쪽이 1개가 되면 오른쪽에 남은 개수가 이을 수 있는 경우의 수가 되므로 이를 활용해서 점화식을 만들 수 있게 된다.

 

dp[i][j] = d[i-1][k-1]+d[i-1][k-2]+ ... + d[i-1][i-1]

 

따라서 이를 반복문으로 구현하면 다음과 같게 된다. 

1
2
3
4
5
6
7
8
9
10
11
T=int(input())
for i in range(T):
    n,m=map(int,input().split())
    d=[[0 for _ in range(m+1)]for _ in range(n+1)]
    for j in range(m+1):
        d[1][j]=j
    for j in range(2,n+1):
        for k in range(j,m+1):
            for l in range(k,j-1,-1):
                d[j][k]+=d[j-1][l-1]
    print(d[n][m])
cs

문제링크:

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

 

1010번: 다리 놓기

입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트케이스에 대해 강의 서쪽과 동쪽에 있는 사이트의 개수 정수 N, M (0 < N ≤ M < 30)이 주어진다.

www.acmicpc.net

 

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[BOJ]1965. 상자넣기  (0) 2019.11.08
[BOJ]2225. 합분해  (0) 2019.11.07
[BOJ]1495. 기타리스트  (0) 2019.11.05
[BOJ]14848. 정수 게임  (0) 2019.11.04
[BOJ] 1325. 효율적인 해킹  (0) 2019.10.31
728x90
반응형

문제:

Day of Mourning의 기타리스트 강토는 다가오는 공연에서 연주할 N개의 곡을 연주하고 있다. 지금까지 공연과는 다른 공연을 보여주기 위해서 이번 공연에서는 매번 곡이 시작하기 전에 볼륨을 바꾸고 연주하려고 한다.

 

먼저, 공연이 시작하기 전에 각각의 곡이 시작하기 전에 바꿀 수 있는 볼륨의 리스트를 만들었다. 이 리스트를 V라고 했을 때, V[i]는 i번째 곡을 연주하기 전에 바꿀 수 있는 볼륨을 의미한다. 항상 리스트에 적힌 차이로만 볼륨을 바꿀 수 있다. 즉, 현재 볼륨이 P이고 지금 i번째 곡을 연주하기 전이라면, i번 곡은 P+V[i]나 P-V[i]로 연주 해야 한다. 하지만 0보다 작은 값으로 볼륨을 바꾸거나, M보다 큰 값으로 볼륨을 바꿀 수 없다.

 

곡의 개수 N과 시작 볼륨 S, 그리고 M이 주어졌을 때, 마지막 곡을 연주할 수 있는 볼륨 중 최댓값을 구하는 프로그램을 작성하시오. 모든 곡은 리스트에 적힌 순서대로 연주해야 한다.

입력:

첫째 줄에 N, S, M이 주어진다. (1<=N<=100, 1<=M<=1000,0<=S<=M) 둘째 줄에는 각 곡이 시작하기 전에 줄 수 있는 볼륨의 차이가 주어진다. 이 값은 1보다 크거나 같고, M보다 작거나 같다.

출력:

첫째 줄에 가능한 마지막 곡의 볼륨 중 최댓값을 출력한다. 만약 마지막 곡을 연주할 수 없다면(중간에 볼륨을 조절을 할 수 없다면) -1을 출력한다.

풀이방법:

 2차원 배열을 사용하는 동적계획법을 사용하면 트리처럼 진행이 된다. 점차 연주가 가능한 볼륨이 많아지긴 하겠지만, 0보다 작은 값이나 초과하는 값들도 들어오기 때문에 생각만큼 많이 증가하지는 않게 된다.

 각 배열은 0으로 초기화 되어 있으며 각 곡마다 연주할 수 있는 볼륨은 1로 바뀌게 된다. 따라서 처음에는 S 자리에만 1로 초기화 되어 있으며 다음 곡의 배열은 이전 곡에서 1인 값에 V[i]를 빼거나 더한 값이 1로 초기화 될 것이다.

 이렇게 마지막 곡까지 위 행위를 반복하고 뒤에서부터 1인 값을 찾아 1이면 값을 넣고 종료시키면 그 값이 최댓값이 될 것이다. 그리고 애초에 -1을 초기값으로 잡아뒀기 때문에 1인 값을 만나지 못하면 연주 할 수 없는 것을 의미하므로 답은 그대로 -1이 될 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
n,s,m=map(int,input().split())
v=list(map(int,input().split()))
 
dp=[[0 for i in range(m+1)] for j in range(n+1)]
dp[0][s]=1
idx=1
while n:
    for i in range(m+1):
        if dp[idx-1][i]==1:
            if i-v[idx-1>= 0:
                dp[idx][i-v[idx-1]]=1
            if i+v[idx-1<=m:
                dp[idx][i+v[idx-1]]=1
    n-=1
    idx+=1
 
answer=-1
for i in range(m,-1,-1):
    if dp[-1][i]==1:
        answer=i
        break
print(answer)
cs

문제링크:

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

 

1495번: 기타리스트

첫째 줄에 N, S, M이 주어진다. (1 ≤ N ≤ 100, 1 ≤ M ≤ 1000, 0 ≤ S ≤ M) 둘째 줄에는 각 곡이 시작하기 전에 줄 수 있는 볼륨의 차이가 주어진다. 이 값은 1보다 크거나 같고, M보다 작거나 같다.

www.acmicpc.net

 

728x90
반응형

'Algorithm > Python' 카테고리의 다른 글

[BOJ]2225. 합분해  (0) 2019.11.07
[BOJ]1010. 다리 놓기  (0) 2019.11.06
[BOJ]14848. 정수 게임  (0) 2019.11.04
[BOJ] 1325. 효율적인 해킹  (0) 2019.10.31
[BOJ]7569. 토마토  (0) 2019.10.30

+ Recent posts