백준 - 11053번 문제가 어려워서 이리저리 해결법을 탐색해봄.
# list를 입력받고 0번째 요소부터 마지막 요소까지 오름차순이 최대 몇개 있는지 조사하여
최대 오름차순 횟수를 반환해줌.
def func(t:list):
cnt = 1
point = t[0]
for i in range(1,len(t)):
if point < t[i]:
cnt += 1
point = t[i]
return cnt
n = int(input())
l = list(map(int, input().split()))
answer = []
# 최대 오름차순이 0번째부터 시작하지 않을 수도 있으니 모든 index부터 조사하여 최대 index
min_num = l[0]
answer.append(func(l[0:]))
for i in range(len(l)):
if min_num>l[i]:
answer.append(func(l[i:]))
print(max(answer))
n = int(input())
arr = list(map(int, input().split()))
dp = [1 for _ in range(n)]
for i in range(n):
for j in range(i):
if arr[i] > arr[j]:
dp[i] = max(dp[i], dp[j]+1)
print(max(dp))
def my_result(m, l):
def func(t:list):
cnt = 1
point = t[0]
for i in range(1,len(t)):
if point < t[i]:
cnt += 1
point = t[i]
return cnt
answer = []
min_num = l[0]
answer.append(func(l[0:]))
for i in range(len(l)):
if min_num>l[i]:
answer.append(func(l[i:]))
return max(answer)
def your_result(n, arr):
dp = [1 for _ in range(n)]
for i in range(n):
for j in range(i):
if arr[i] > arr[j]:
dp[i] = max(dp[i], dp[j]+1)
return max(dp)
import random
if __name__=="__main__":
cnt = 0
for num in range(1,1000+1):
rand_list = [random.choice(range(1,1000+1)) for _ in range(num)]
if my_result(num, rand_list)!=your_result(num, rand_list):
cnt += 1
print(cnt)
내 코드(my_result)와 인터넷에서 찾은 정답 코드(your_result) 두가지를
문제에서 제시된 기준 (1 N 1,000) / 수열 (1 1,000)을 적용하여
random 모듈로 조사해봄.
=> 1,000번 시행 중 991번이 서로 다른 답을 내놓고 있음.
사실상 내 코드는 예제 입력 코드만 맞추는 수준
def my_result(m, l):
def func(t:list):
cnt = 1
point = t[0]
for i in range(1,len(t)):
if point < t[i]:
cnt += 1
point = t[i]
return cnt
answer = []
min_num = l[0]
answer.append(func(l[0:]))
for i in range(len(l)):
if min_num>l[i]:
answer.append(func(l[i:]))
return max(answer)
def your_result(n, arr):
dp = [1 for _ in range(n)]
for i in range(n):
for j in range(i):
if arr[i] > arr[j]:
dp[i] = max(dp[i], dp[j]+1)
return max(dp)
import random
if __name__=="__main__":
cnt = 0
for num in range(1,1000+1):
rand_list = [random.choice(range(1,1000+1)) for _ in range(num)]
my_code = my_result(num, rand_list)
your_code = your_result(num, rand_list)
if my_code != your_code:
print(f"num: {num} \n rand_list:{rand_list}")
print(f"my_code: {my_code} \n your_code: {your_code}")
break
3번 코드에서 마지막 부분만 조금 수정해줬다.
만약 내 코드와 정답 코드가 다를 경우 각각 num과 rand_list
그리고 내 코드와 정답 코드의 값을 출력하도록 만들었다.
너무 많은 시행을 할까봐
1개만 찾아도 바로 반복을 중단하도록 하였다.
num: 8
rand_list:[952, 8, 961, 550, 681, 226, 934, 672]
my_code: 3
your_code: 4
정답은 8 -> 550 -> 681 -> 934 로 4가 나와야하는데 내가 작성한 코드는 3이 나왔다.
나의 코드는
8 다음으로 나온 961을 point 변수에 담고
그 다음 요소들을 각각 961과 비교 했기 때문에 최대 길이인 4가 나오지 않았던것!
n = int(input())
arr = list(map(int, input().split()))
dp = [1 for _ in range(n)]
for i in range(n):
for j in range(i):
if arr[i] > arr[j]:
dp[i] = max(dp[i], dp[j]+1)
print(max(dp))
위 코드에서 핵심은 아래 부분인데
for i in range(n):
for j in range(i):
if arr[i] > arr[j]:
dp[i] = max(dp[i], dp[j]+1)
arr[i]와 arr[j]를 비교하여 arr[i]가 클 경우
dp[i]에 dp[i]와 dp[j]+1 중 큰 수를 입력함.
| idx | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| i | ▲ | |||||||
| j | ▲ | |||||||
| arr | 952 | 8 | 961 | 550 | 681 | 226 | 934 | 672 |
| dp | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
| idx | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| i | ▲ | |||||||
| j | ▲ | ▲ | ||||||
| arr | 952 | 8 | 961 | 550 | 681 | 226 | 934 | 672 |
| dp | 1 | 1 | 2 | 1 | 1 | 1 | 1 | 1 |
(arr[j==0], arr[j==1] 두 요소보다 크다고 해서 dp[2]가 3이 되는게 아님!)
| idx | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| i | ▲ | |||||||
| j | ▲ | ▲ | ▲ | |||||
| arr | 952 | 8 | 961 | 550 | 681 | 226 | 934 | 672 |
| dp | 1 | 1 | 2 | 2 | 1 | 1 | 1 | 1 |
(dp[2]가 2라고 해서 dp[3]에 3을 입력하는게 아님!)
| idx | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| i | ▲ | |||||||
| j | ▲ | ▲ | ▲ | ▲ | ||||
| arr | 952 | 8 | 961 | 550 | 681 | 226 | 934 | 672 |
| dp | 1 | 1 | 2 | 2 | 3 | 1 | 1 | 1 |
| idx | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| i | ▲ | |||||||
| j | ▲ | ▲ | ▲ | ▲ | ▲ | |||
| arr | 952 | 8 | 961 | 550 | 681 | 226 | 934 | 672 |
| dp | 1 | 1 | 2 | 2 | 3 | 2 | 1 | 1 |
| idx | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| i | ▲ | |||||||
| j | ▲ | ▲ | ▲ | ▲ | ▲ | ▲ | ||
| arr | 952 | 8 | 961 | 550 | 681 | 226 | 934 | 672 |
| dp | 1 | 1 | 2 | 2 | 3 | 2 | 4 | 1 |
| idx | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| i | ▲ | |||||||
| j | ▲ | ▲ | ▲ | ▲ | ▲ | ▲ | ▲ | |
| arr | 952 | 8 | 961 | 550 | 681 | 226 | 934 | 672 |
| dp | 1 | 1 | 2 | 2 | 3 | 2 | 4 | 3 |
max(dp) = 4문제에 제출한 코드가 오답이고 아무리 생각해봐도 정답이 뭔지 모르겠음.
=> 검색을 통해 정답 코드를 확인함. 그래도 어떤 구조인지 모르겠음.
=> 내 코드와 정답 코드를 random 모듈을 통해 문제 조건에 맞게 랜덤한 값을 입력하여 반례를 찾음.
=> 반례를 통해 내 코드에 어떤 부분이 틀렸는지 확인함.
=> 반례를 통해 정답 코드가 어떤 구조로 돌아가는지 확인함.
이렇게 아무리 생각해도 정답 원리가 떠오르지 않는 문제를
하나하나 차근차근 분석해봤다.
비록 실버2 문제긴 하지만
이를 발판으로 조금 더 고수준의 문제도 풀며 효율적인 코드를 짜는
개발자가 되었으면 좋겠다.