N,M = map(int,input().split())
INF= float('inf')
dp = [INF]*(M+1)
apps_memory = list(map(int,input().split()))
apps_value = list(map(int,input().split()))
for i in range(N):
    memory,value = apps_memory[i],apps_value[i]
    for k in range(M,-1,-1):
        if k == 0:
            if memory >=M:
                memory = M
            dp[memory] = min(dp[memory],value)
        else:
            if dp[k]:
                num_memory = k + memory
                if num_memory >=M:
                    dp[M] = min(dp[M],dp[k]+value)
                else:
                    dp[num_memory] = min(dp[num_memory],dp[k]+value)
print(dp[M])

 

 

 

N,M = map(int,input().split())
INF= float('inf')

apps_memory = list(map(int,input().split()))
apps_value = list(map(int,input().split()))
total_sum = sum(apps_value)

dp = [0]*(total_sum+1)
result = INF
for i in range(N):
    for j in range(total_sum,apps_value[i]-1,-1):
        if j - apps_value[i] >=0:
            dp[j] = max(dp[j],dp[j-apps_value[i]]+apps_memory[i])
        if dp[j] >= M:
            result = min(j,result)

print(result)



 

T = int(input())
dp = [[0]*10 if i !=0 else [1]*10 for i in range(65)]
visited = [0]*64
visited[0] = 1
last_n = 0
for ind in range(T):
    n = int(input())
    if visited[n-1]:
        print(sum(dp[n-1]))
    else:
        for ind in range(last_n+1,n):
            for num in range(9,-1,-1):
                if num == 9:
                    dp[ind][num] = sum(dp[ind-1])
                else:
                    dp[ind][num] = dp[ind][num+1] - dp[ind-1][num+1]
        last_n = max(last_n,n-1)

        print(sum(dp[n-1]))
T = int(input())
dp = [[1]*10 if ind == 0 else [0]*10 for ind in range(64)]
result = [0]*64
result[0] = 10
for ind in range(1,64):
    for num in range(9,-1,-1):
        if num == 9:
            dp[ind][num] = result[ind-1]
        else:
            dp[ind][num] = dp[ind][num+1] - dp[ind-1][num+1]
    result[ind] = sum(dp[ind])

for _ in range(T):
    n = int(input())
    print(result[n-1])
def checkminNumber(index,open1,open2):
    if index > M-1:
        return 0 
    result = dp[index][open1][open2]
    if result != float('inf'):
        return result
    next_open = output_list[index]
    dp[index][open1][open2] = min(abs(open1 - next_open) + checkminNumber(index+1,next_open,open2), abs(open2 - next_open) + checkminNumber(index+1,open1,next_open))
    return dp[index][open1][open2]



N = int(input())

open1,open2 = list(map(int,input().split()))

M = int(input())
dp = [[[float('inf')]*(N+1) for _ in range(N+1)] for _ in range(M)]
output_list = []

for _ in range(M):
    output_list.append(int(input()))
print(checkminNumber(0,open1,open2))

 

N = int(input())

arr = [int(input()) for _ in range(N)]

dp = [[0 for _ in range(3)] for _ in range(N)] 
if N>2:
    dp[0][1] = arr[0]
    dp[1][1] = arr[1]
    dp[1][2] = dp[0][1] + arr[1]



    for ind in range(2,N):
        
        dp[ind][0] = max(dp[ind-1][0],dp[ind][0],dp[ind-2][2],dp[ind-2][1],dp[ind-1][1])
        dp[ind][1] = max(dp[ind][1],dp[ind-1][0]+arr[ind],dp[ind-2][1]+arr[ind],dp[ind-2][2]+arr[ind],dp[ind-2][0]+arr[ind])
        dp[ind][2] = max(dp[ind][2],dp[ind-1][1]+arr[ind])
    print(max(list(map(max,dp))))
else:
    print(sum(arr))

 

 

N = int(input())

arr = [0]+[int(input()) for _ in range(N)]

dp = [0]*(N+1)

dp[1] = arr[1]

for ind in range(2,N+1):
    if ind == 2:
        dp[ind] = dp[ind-1] + arr[ind]
    else:
        dp[ind] = max(dp[ind-3]+arr[ind-1]+arr[ind],dp[ind-2]+arr[ind],dp[ind-1])

print(dp[N])

'알고리즘 > 백준_복기_미완료' 카테고리의 다른 글

[BOJ/백준] 2436 공약수  (0) 2021.05.02
[BOJ/백준] 2122 센서  (0) 2021.05.02
[BOJ/백준] 2141 우체국  (0) 2021.05.02
[BOJ/백준] 2098 외판원 순회  (0) 2021.05.02
[BOJ/백준] 2031 이 쿠키 달지 않아!  (0) 2021.05.02
def TSP(ind,visited_city):
    if dp[ind][visited_city] != INF:
        return dp[ind][visited_city]
    if visited_city == (1<<N)-1:
        if arr[ind][0]:
            return arr[ind][0]
        else:
            return INF

    for next_city in range(N):
        if not (visited_city&1<<next_city) and arr[ind][next_city]:
            temp = TSP(next_city,visited_city|1<<next_city) + arr[ind][next_city]
            dp[ind][visited_city] = min(dp[ind][visited_city],temp)

    return dp[ind][visited_city]





N = int(input())
arr = [list(map(int,input().split())) for _ in range(N)]

INF = float('inf')
dp = [[INF]*(2**N) for _ in range(N)]

print(TSP(0,1))
T,N,D,K = map(int,input().split())

arr = list(map(int,input().split()))

arr.sort()
tea_cnt = [0]*N
for ind in range(N):
    left = ind
    right = N-1
    tea_time = arr[ind]
    while left <=right:
        mid = (left+right)//2

        if arr[mid] >= tea_time+D:
            right = mid -1
        else:
            left = mid + 1
    tea_cnt[ind] = left - ind

dp = [[0]*(K+1) for _ in range(N+1)]
for idx in range(N):
    for drink_coffee in range(1,K+1):
        dp[tea_cnt[idx]+idx][drink_coffee] = max(dp[tea_cnt[idx]+idx][drink_coffee], dp[idx][drink_coffee-1]+tea_cnt[idx])
        dp[idx+1][drink_coffee] = max(dp[idx+1][drink_coffee],dp[idx][drink_coffee])
for row in dp:
    print(row)
print(max(map(max,dp)))

'알고리즘 > 백준_복기_미완료' 카테고리의 다른 글

[BOJ/백준] 2141 우체국  (0) 2021.05.02
[BOJ/백준] 2098 외판원 순회  (0) 2021.05.02
[BOJ/백준] 1949 우수 마을  (0) 2021.05.02
[BOJ/백준] 1722 순열의 순서  (0) 2021.05.02
[BOJ/백준] 1405 미친 로봇  (0) 2021.05.02
def solution(ind,diff):
    if diff > 250000:
        return -INF
    if ind == N:
        if diff == 0:
            return 0
        else:
            return -INF
    if dp[ind][diff] != -1:
        return dp[ind][diff]

    dp[ind][diff] = solution(ind+1,diff+arr[ind])
    dp[ind][diff] = max(dp[ind][diff],solution(ind+1,diff))
    if arr[ind] > diff:
        dp[ind][diff] = max(dp[ind][diff],diff + solution(ind+1,arr[ind]-diff))
    else:
        dp[ind][diff] = max(dp[ind][diff],arr[ind] + solution(ind+1,diff-arr[ind]))
    return dp[ind][diff]

N = int(input())
arr = list(map(int,input().split()))
arr = arr + [0]
INF = float('inf')
dp = [[-1] * 500001 for _ in range(N+1)]

result = solution(0,0)
if result == 0:
    print(-1)
else:
    print(result)

 

힘들게 풀었던 문제이다.

 

dp의 테이블에서 행은 현재의 index를 말하며, 열은 두 탑의 격차의 절대값을 말한다.

 

재귀함수를 통해 짰는데.

 

첫번째 : 해당 블록을 높이가 더 높은 쪽에 놓았을때,

 

두번째 : 해당 블록을 놓지 않았을때

 

세번째 : 높이가 낮은 블록에 놓았을 때 : 이 때 주의해야할 것은 현재 공통적으로 쌓아올려진 높이는 diff와 arr[ind]의 두 크기 중 작은 것에 된다.

 

이렇게 3가지 경우로 나뉘며, 세번째에는 격차가 클때와 현재 블록이 클때로 나뉘어서 된다.

 

 

이렇게 재귀를 하면서 마지막에서 들어온 diff가 0이면 높이가 같은것이므로 0을 반환해주고, 그게 아니면 두 높이가 다른것이므로, -INF를 반환해준다.

 

 

이게 내 첫번째 풀이였고, 실행시간은 3900ms로 엄청 느렸다.

 

그래서 다른 사람 풀이를 보고 공부한 코드는 다음과 같다.

import sys
input = sys.stdin.readline

N = int(input())
arr = list(map(int,input().split()))

if N == 1:
    print(-1)
else:
    total_sum = sum(arr)
    dp = [[-1] * total_sum for _ in range(N)]
    dp[0][0] = 0
    dp[0][arr[0]] = arr[0]
    for ind in range(N-1):
        for j in range(total_sum//2+1):
            if dp[ind][j] != -1:
                # 다음 거의 블록을 쓰지 않을때
                dp[ind+1][j] = max(dp[ind][j],dp[ind+1][j])
                # 두 탑 중 더 높은 탑쪽에 블록을 쌓을때
                if j + arr[ind+1] < total_sum:
                    dp[ind+1][j+arr[ind+1]] = max(dp[ind+1][j+arr[ind+1]],dp[ind][j]+arr[ind+1])
                # 더 낮은 탑 쪽에 쌓는데 새로 쌓는 블록이 기존 블록보다 높을때 와 아닐때
                if arr[ind+1] > j:
                    dp[ind+1][arr[ind+1]-j] = max(dp[ind+1][arr[ind+1]-j],dp[ind][j] + arr[ind+1]-j)
                else:
                    dp[ind+1][j-arr[ind+1]] = max(dp[ind+1][j-arr[ind+1]],dp[ind][j])
    if dp[-1][0] == 0:
        print(-1)
    else:
        print(dp[-1][0])

 

 

위와 dp 테이블은 동일하다. 그런데 전체 input의 합을 구하고, 그거의 반만큼만 반복을 돌리도록 했다.

 

그래서 위에서는 재귀를 통해서 돌아가다 보니, 무조건 3개의 함수가 실행되다보니 밑의 코드보다 훨씬 오래걸린다.

 

밑의 코드는 50*250000이 최대 횟수로 볼수 있으므로, 위의 것보다 연산량에 이득을 본것 같다.

 

여기도 위와 비슷하게,

 

아무것도 놓지 않았을때

두 탑 중 더 높은 탑쪽에 쌓았을때,

두 탑 중 더 낮은 탑쪽에 쌓았을때,

 

를 구분해서 놓으면 된다.

 

그리고 dp에 저장되는 값은 해당 index에서 두 탑의 높이가 diff만큼 차이가 날때, 그때 더 높은탑의 크기를 저장해놓는 것이므로,

 

그것을 잘 구분해서, dp에 저장시켜주면 된다.

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

[BOJ/백준] 1194 달이 차오른다 가자  (0) 2021.05.11
[BOJ/백준] 2933 미네랄  (0) 2021.05.10
[BOJ/백준] 1071 소트  (0) 2021.05.02
[BOJ/백준] 1062 가르침  (0) 2021.05.02
[BOJ/백준] 1976 여행 가자  (0) 2021.04.08
# 2225번 합분해


N,K = map(int,input().split())

dp = [[1]*(N+1) if i==0 else [0]*(N+1) for i in range(K)]


for ind in range(1,K):
    for prev_num in range(N,-1,-1):
        for current_num in range(N,-1,-1):
            if prev_num + current_num <=N:
                dp[ind][prev_num+current_num] += dp[ind-1][prev_num]


print(dp[K-1][N]%1000000000)

K 번을 더햇 N이 나오는 경우이므로, DP를 (N+1)*K 형태로 만들어 놨다. 그래서 이전 행에서의 prev_num과 현재의 current_num을 더해서 N을 넘지 않는 경우 새로운 행에 그 횟수를 저장해주는 방식을 해주었다.

 

 

N,K = map(int,input().split())

dp = [[1]*(N+1) if ind==0 else [0]*(N+1) for ind in range(K)]


for k in range(1,K):
    for num in range(N+1):
        dp[k][num] = (dp[k-1][num] + dp[k][num-1])%1000000000

print(dp[K-1][N])

위의 방식대로 풀어도 시간내에 통과하지만 점화식을 구하면 좀 더 쉽게 구할 수 있다.

 

DP[K][N] = DP[K-1][N] + DP[K-1][N-1] + .... + DP[K-1][0] 이다.

DP[K][N-1] = DP[K-1][N-1] + DP[K-1][N-2] + .... + DP[K-1][0] 인 것을 알 수 있따.

 

이것을 봐보면 DP[K][N] = DP[K-1][N] + DP[K][N-1]인 것을 알 수 있다.

 

이 점화식을 통해 구하면 좀 더 쉽게 구할 수 있다.

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

[BOJ/백준] 2493 탑  (0) 2021.02.16
[BOJ/백준] 1915 가장 큰 정사각형  (0) 2021.02.16
[BOJ/백준] 3190 뱀  (0) 2021.02.16
[BOJ/백준] 10026 적록색약  (0) 2021.02.16
[BOJ/백준] 14503 로봇 청소기  (0) 2021.02.16

+ Recent posts