오히려 좋아..

상황이 나쁘게만 흘러가는 것 같을 때 외쳐보자.. .

궁금한 마음으로 포트폴리오 보기

Algorithm/백준 온라인 저지(BOJ)

08/30 카드게임 BOJ 10835 파이썬

junha6316 2020. 8. 30. 15:55

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

 

10835번: 카드게임

첫 줄에는 한 더미의 카드의 개수를 나타내는 자연수 N(1 ≤ N ≤ 2,000)이 주어진다. 다음 줄에는 왼쪽 더미의 카드에 적힌 정수 A(1 ≤ A ≤ 2,000)가 카드 순서대로 N개 주어진다. 그 다음 줄에는 오��

www.acmicpc.net

1. 풀이

다이나믹 프로그래밍 문제다.

규칙 1, 2, 3에 따라 채워가면 되는 문제로 bottom up 방식을 사용했다.

 

* 먼저 카드 개수가 N이라고 할 때 N*N을 만들고 뒤쪽에서 부터 채워간다.

* i 인덱스는 left의 카드번호 j 인덱스는 right 의 카드번호를 의미한다.

* left[i] > right[j] 인 경우에는 오른쪽 카드를 버리고 스코어에 버린 카드 번호의 값을 더할 수 있고 그외의 경우에는 없다.

 

아래는 파이썬 코드이다. (Bottom up 방식)

import sys
input= sys.stdin.readline
n = int(input())
left = list(map(int, input().split()))
right = list(map(int, input().split()))
dp = [[0]*(n+1) for _ in range(n+1)]

for i in range(n-1, -1, -1):
    for j in range(n-1, -1, -1):
        if right[j] < left[i]:
            dp[i][j] = max(dp[i][j+1] + right[j], dp[i+1][j], dp[i+1][j+1])
        else:
            dp[i][j] = max(dp[i+1][j], dp[i+1][j+1])

print(dp[0][0])

top down 방식

N = int(input())
left =[0] +list(map(int, input().split()))
right= [0]+list(map(int, input().split()))

dp = [[0 for i in range(N+1)] for i in range(N+1)]

for row in range(1,N+1):
    for col in range(1,N+1):
        if right[col] < left[row]:
            dp[row][col] = max(dp[row][col-1] + right[col], dp[row-1][col], dp[row-1][col-1])
        else:
            dp[row][col] = max(dp[row-1][col], dp[row-1][col-1])

print(dp[N][N])