Skip to content

Commit ebb1d36

Browse files
authored
Merge pull request #97 from AlgorithmStudy-Allumbus/minjeong
Minjeong / 11월 5주차 / 8문제
2 parents 1eb63e3 + 301fb6f commit ebb1d36

8 files changed

+162
-0
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import sys
2+
input = sys.stdin.readline
3+
4+
# 1️⃣ 입력 받기
5+
n = int(input()) # 수열의 크기
6+
nums = list(map(int, input().split())) # 수열
7+
dp = [1] * n # DP 배열 초기화 (모든 원소 길이 1로 초기화)
8+
9+
# 2️⃣ DP 계산
10+
for i in range(n): # 현재 원소
11+
for j in range(i): # 이전 원소들과 비교
12+
if nums[i] < nums[j]: # 감소 조건
13+
dp[i] = max(dp[i], dp[j] + 1)
14+
15+
# 3️⃣ 결과 출력
16+
print(max(dp)) # dp 배열 중 가장 큰 값 출력
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import sys
2+
input = sys.stdin.readline
3+
4+
# 1️⃣ 입력 받기
5+
n = int(input()) # 수열의 크기
6+
nums = list(map(int, input().split())) # 수열
7+
dp = [1] * n # DP 배열 초기화 (모든 원소 길이 1로 초기화)
8+
9+
# 2️⃣ DP 계산
10+
for i in range(n): # 현재 원소
11+
for j in range(i): # 이전 원소들과 비교
12+
if nums[i] < nums[j]: # 감소 조건
13+
dp[i] = max(dp[i], dp[j] + 1)
14+
15+
# 3️⃣ 결과 출력
16+
print(max(dp)) # dp 배열 중 가장 큰 값 출력
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import sys
2+
input = sys.stdin.readline
3+
4+
# 입력
5+
N, K = map(int, input().split()) # N: 물품의 수, K: 버틸 수 있는 무게
6+
items = [[0, 0]]
7+
for _ in range(N):
8+
items.append(list(map(int, input().split())))
9+
10+
# DP 채우기
11+
knapsack = [[0] * (K+1) for _ in range(N+1)] # DP표는 0~K+1, 0~N+1로 구성
12+
13+
for i in range(1, N+1):
14+
for j in range(1, K+1):
15+
weight = items[i][0]
16+
value = items[i][1]
17+
18+
if j >= weight: # "현재최대무게j가 해당물건무게 weight보다 큰 경우
19+
# 표의 윗 셀의 값과 현재물건의 value + 이전물건의 value값의 최댓값을 knapsack[i][j]에 저장
20+
knapsack[i][j] = max(knapsack[i-1][j], knapsack[i-1][j-weight] + value)
21+
else: # # "현재최대무게j가 해당물건무게 weight 보다 작은 경우 (현재 물건을 담을 수 없는 경우)
22+
# 이전 값을 가져온다.
23+
knapsack[i][j] = knapsack[i-1][j]
24+
25+
# 최대 가치
26+
print(knapsack[N][K])
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import sys
2+
input = sys.stdin.readline
3+
4+
# 1️⃣ DP 배열 초기화
5+
dp = [1] * 101 # 최대 N=100까지 미리 계산
6+
for i in range(4, 101): # P(4)부터 점화식 적용
7+
dp[i] = dp[i - 2] + dp[i - 3]
8+
9+
# 2️⃣ 테스트케이스 입력 처리
10+
T = int(input()) # 테스트케이스 수
11+
for _ in range(T):
12+
N = int(input()) # N 입력
13+
print(dp[N]) # 미리 계산된 DP에서 값 출력
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import sys
2+
input = sys.stdin.readline
3+
4+
# 1. 입력받기
5+
n = int(input()) # 상자의 개수
6+
boxes = list(map(int, input().split())) # 상자의 크기 배열
7+
8+
# 2. DP 초기화
9+
dp = [1] * n # 모든 상자는 최소 자기 자신을 포함하므로 초기값 1
10+
11+
# 3. DP 계산
12+
for i in range(n): # i는 현재 상자를 가리킴
13+
for j in range(i): # j는 i 이전의 상자를 가리킴
14+
if boxes[j] < boxes[i]: # j번째 상자가 i번째 상자 안에 들어갈 수 있는 경우
15+
dp[i] = max(dp[i], dp[j] + 1) # dp 갱신: 기존 값 vs j까지의 값 + 1
16+
17+
# 4. 정답 출력
18+
print(max(dp)) # dp 배열에서 최대값이 한 번에 넣을 수 있는 최대 상자 개수
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import sys
2+
input = sys.stdin.readline
3+
4+
# 1. 입력받기
5+
n = int(input()) # 아이들의 수 N 입력
6+
lines = [int(input()) for _ in range(n)] # 현재 줄 서 있는 상태 입력
7+
8+
# 2. DP 초기화
9+
dp = [1] * n # LIS를 계산하기 위한 초기화 (모든 값 1로 시작)
10+
11+
# 3. LIS 계산
12+
for i in range(1, n): # 현재 위치 i를 기준으로
13+
for j in range(i): # i보다 앞에 있는 모든 j를 탐색
14+
if lines[i] > lines[j]: # 앞 번호가 현재 번호보다 작을 때
15+
dp[i] = max(dp[i], dp[j] + 1) # LIS 길이를 갱신
16+
17+
# 4. 가장 긴 증가하는 부분 수열의 길이 찾기
18+
lis_length = max(dp)
19+
20+
# 5. 최소로 옮겨야 하는 아이들의 수 출력
21+
print(n - lis_length)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import sys
2+
input = sys.stdin.readline
3+
4+
# 1. 입력 처리
5+
n = int(input()) # 수열의 크기
6+
nums = list(map(int, input().split())) # 수열 A
7+
8+
# 2. 증가 부분 수열 계산 (왼쪽 → 오른쪽)
9+
inc = [1] * n
10+
for i in range(n):
11+
for j in range(i):
12+
if nums[i] > nums[j]:
13+
inc[i] = max(inc[i], inc[j] + 1)
14+
15+
# 3. 감소 부분 수열 계산 (오른쪽 → 왼쪽)
16+
dec = [1] * n
17+
for i in range(n - 1, -1, -1):
18+
for j in range(i + 1, n):
19+
if nums[i] > nums[j]:
20+
dec[i] = max(dec[i], dec[j] + 1)
21+
22+
# 4. 가장 긴 바이토닉 수열의 길이 계산
23+
result = 0
24+
for i in range(n):
25+
result = max(result, inc[i] + dec[i] - 1)
26+
27+
# 5. 결과 출력
28+
print(result)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import sys
2+
input = sys.stdin.readline
3+
4+
# 1. 입력받기
5+
N, K = map(int, input().split()) # N: 최대 공부 시간, K: 과목 수
6+
lectures = [[0, 0]] # 수강 과목 리스트 (중요도, 필요한 공부 시간)
7+
for _ in range(K):
8+
lectures.append(list(map(int, input().split()))) # 중요도와 공부 시간
9+
10+
# 2. DP 초기화
11+
dp = [[0] * (N + 1) for _ in range(K + 1)]
12+
13+
# 3. DP 채우기(냅색 알고리즘)
14+
for i in range(1, K + 1): # 각 과목에 대해
15+
importance = lectures[i][0] # 중요도
16+
time = lectures[i][1] # 필요한 공부 시간
17+
for j in range(1, N + 1): # 공부 시간 1부터 N까지
18+
if j >= time: # 현재 공부 시간으로 이 과목을 선택 가능 -> 더 큰 값으로 갱신
19+
dp[i][j] = max(dp[i-1][j], dp[i-1][j-time] + importance)
20+
else: # 충족할 수 없다 -> 이전 값 유지
21+
dp[i][j] = dp[i-1][j]
22+
23+
# 4. 결과 출력
24+
print(dp[K][N])

0 commit comments

Comments
 (0)