금광의 모든 위치에 대하여, 3가지 경우(왼쪽 위에서 오는 경우, 왼쪽 아래에서 오는 경우, 왼쪽에서 오는 경우)를 비교하고,왼쪽에서의 가장 많은 금을, 현재 위치의 금에 더해줌으로써 문제를 해결해야함.
dp[i][j] += max(dp[i-1][j-1], dp[i][j-1], dp[i+1][j-1])
"""
2
3 4
1 3 3 2 2 1 4 1 0 6 4 7
4 4
1 3 1 5 2 2 4 1 5 0 2 3 0 6 1 2
"""
import sys
# 테스트 케이스 입력
t = int(sys.stdin.readline())
for _ in range(t):
# 금광 정보 입력
n, m = map(int, sys.stdin.readline().split())
gold_input = list(map(int, sys.stdin.readline().split()))
# 다이나믹 프로그래밍을 위한 2차원 DP 테이블 초기화
gold = []
for i in range(n):
gold.append(gold_input[i*m:i*m+m])
# 다이나믹 프로그래밍 진행
for j in range(1, m):
for i in range(n):
# 왼쪽 위가 없다면
if ( i == 0 ):
gold[i][j] += max(gold[i][j-1], gold[i+1][j-1])
# 왼쪽 아래가 없다면
elif ( i == n - 1):
gold[i][j] += max(gold[i-1][j-1], gold[i][j-1])
# 왼쪽 위와 왼쪽 아래가 다 있다면
else:
gold[i][j] += max(gold[i-1][j-1], gold[i][j-1], gold[i+1][j-1])
# 채굴자가 얻을 수 있는 금의 최대 크기 비교
result = 0
for i in range(n):
result = max(result, gold[i][m - 1])
print(result)
계속 누적합을 하게 되어서 삼각형 형태의 크기 비교가 안됨
def solution(triangle):
answer = 0
s = len(triangle)
graph = [[0] * s for _ in range(s)]
graph[0][0] = triangle[0][0]
maxV = -1e9
for i in range(s-1):
for j in range(s):
graph[i+1][j]=triangle[i+1][j]+graph[i][j]
maxV=max(maxV, graph[i][j])
return maxV
def solution(triangle):
# dp 테이블 초기화
dp = [[0] * len(triangle) for _ in range(len(triangle))]
dp[0][0] = triangle[0][0]
# 거쳐간 숫자의 최댓값 구하기
for i in range(len(triangle) - 1):
for j in range(len(triangle[i])):
dp[i + 1][j] = max(dp[i + 1][j], dp[i][j] + triangle[i + 1][j])
dp[i + 1][j + 1] = max(dp[i + 1][j + 1], dp[i][j] + triangle[i + 1][j + 1])
return max(dp[-1]) # dp 테이블의 마지막 원소들 중 최댓값 반환
print(solution([[7], [3, 8], [8, 1, 0], [2, 7, 4, 4], [4, 5, 2, 6, 5]]))
뒤쪽부터 매 상담에 대하여 현재 상담 일자의 이윤(p[i]) + 현재 상담을 마친 일자부터의 최대 이윤(dp[t[i] + i]])
을 계산
dp[i] = max(p[i] + dp[t[i] + i], max_value)
"""
1일 2일 3일 4일 5일 6일 7일
Ti 3 5 1 1 2 4 2
Pi 10 20 10 20 15 40 200
7
3 10
5 20
1 10
1 20
2 15
4 40
2 200
"""
import sys
# 전체 상담 개수
n = int(sys.stdin.readline())
t = [] # 각 상담을 완료하는데 걸리는 기간
p = [] # 각 상담을 완료했을 때 받을 수 있는 금액
dp = [0] * (n + 1) # i번째 날부터 마지막 날까지 낼 수 있는 최대 이익
max_value = 0
for _ in range(n):
x, y = map(int, sys.stdin.readline().split())
t.append(x)
p.append(y)
# 리스트를 뒤에서부터 거꾸로 확인
for i in range(n-1, -1, -1):
# i번째 날짜에 상담이 가능한 경우
if (i + t[i] <= n):
# (현재 상담 날짜의 금액 + 다음 상담 날짜의 누적 금액)과
# 현재 상담 날짜부터 마지막 날까지 쌓을 수 있는 최대 누적 금액을 비교
dp[i] = max(p[i] + dp[i+t[i]], max_value)
max_value = dp[i]
# i번째 날짜에 상담이 불가능한 경우
else:
dp[i] = max_value
print(max_value)
[알고리즘] 최장 증가 부분 수열(LIS) 알고리즘
📌 최장 증가 부분 수열(LIS, Longest Increasing Subsequence)란?
원소가 n개인 배열의 일부 원소를 골라내서 만든 부분 수열 중, 각 원소가 이전 원소보다 크다는 조건을 만족하고, 그 길이가 최대인 부분 수열을 최장 증가 부분 수열이라고 한다.
- 예를 들어, { 6, 2, 5, 1, 7, 4, 8, 3} 이라는 배열이 있을 경우, LIS는 { 2, 5, 7, 8 }이다
{ 2, 5 }, { 2, 7 } 등 증가하는 부분 수열은 많지만 그 중에서 가장 긴 것이 { 2, 5, 7, 8 }이다
"""
ugly = [2,3,5]
[1,2,3,4,5,6,8,9,12,15]
"""
n=int(input())
ugly = [2,3,5]
answer = [1]
cnt=1
while True:
i=2
for x in ugly: # [2,3,5]
if i % x in ugly:
answer.append(i)
i += 1
cnt += 1
if cnt==n:
print(answer)
break
print(answer[n-1])
n = int(input())
ugly = [False]*1001
ugly[1] = True
for i in range(2, 1001):
if i%2==0:
ugly[i] = True
elif i%3==0:
ugly[i] = True
elif i%5==0:
ugly[i] = True
answer = []
for i in range(len(ugly)):
if ugly[i] == True:
answer.append(i)
print(answer[n-1])
"""
편집거리
삽입 : 문자 추가
삭제 : 문자 삭제
교체 : 문자를 교체
SUNDAY
SATURDAY
SUNDAY #UN
SATURDAY #ATUR
S[A삽입][N삭제][T추가]U[R추가]DAY
같은 문자열이 있는지 확인 + 같은 문자열 따로 save[]=저장 // s2에 맞춰 문자열 순서 고려해야함(이동때문에)
save에 S2와 같은문자가 있으면 그대로 answer[] append (위치가 다르면 이동이됨!)
save에 없으면
"""
s1 = input() #sunday
s2 = input() #saturday
save = [] # SAYDU
answer = []
for i in range(len(s2)):
if s2[i] in s1:
save.append(s2[i])
# save에 중복 문자 들어옴 // 테케에서 오류남
save = set(save)
save = list(save)
cnt=0
for c in s2:
if c in save:
answer.append(c)
else:
answer.append(c)
cnt+=1
print(cnt)
편집거리 알고리즘
편집거리 알고리즘은 두 문자열의 유사도를 판단하는 알고리즘이다.
- PYTHON, PHOTO
두값이 같으면 이전값을 그대로 가져오기
두값이 다르면 dp[i-1][j], dp[i][j-1], dp[i-1][j-1] 중 최소값에 1을 더해서 dp[i][j]에 저장
- 비교
- 참고자료 : https://joyjangs.tistory.com/38
INF = 1e9
# 도시(vertex), 버스(edge) 입력받기
N = int(input())
M = int(input())
# 플로이드-워셜은 2차원 배열이 필요하다.
graph = [[INF] * (N + 1) for _ in range(N + 1)]
for i in range(1, N + 1):
graph[i][i] = 0
for _ in range(M):
a, b, c = map(int, input().split())
# 더 비용이 적다면 최신화
graph[a][b] = min(graph[a][b], c)
for k in range(1, N + 1):
for a in range(1, N + 1):
for b in range(1, N + 1):
graph[a][b] = min(graph[a][b], graph[a][k] + graph[k][b])
for x in range(1, N + 1):
for y in range(1, N + 1):
if graph[x][y] == INF:
print(0, end=' ')
else:
print(graph[x][y], end=' ')
print()