-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
18-H0ngJu #199
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저는 브루트포스로 매번 새로운 리스트를 만들어서 넘겨줬네요... 변수가 많아서 좀 오래걸렸습니다..ㅎ
import java.io.BufferedReader
import java.io.InputStreamReader
import kotlin.math.max
var egg_count_max = 0
fun main() {
val br = BufferedReader(InputStreamReader(System.`in`))
val n = br.readLine().toInt()
val heart = Array(n) { 0 }
val weight = Array(n) { 0 }
repeat(n) {
val (h, w) = br.readLine().split(" ").map { it.toInt() }
heart[it] = h
weight[it] = w
}
hit(n, 0, heart.toList(), weight.toList())
println(egg_count_max)
}
private fun hit(n: Int, now: Int, heart: List<Int>, weight: List<Int>) {
// 끝에 도달
if (now == n) {
egg_count_max = max(egg_count_max, heart.count { it <= 0 })
return
}
// 끝에 도달하지 않아도 더 깰 계란이 없음
if (n - 1 == heart.count { it <= 0 }) {
egg_count_max = max(egg_count_max, n - 1)
return
}
// 이미 now 가 깨졌으면 안깨고 넘기기
if (heart[now] <= 0) {
hit(n, now + 1, heart, weight)
return
}
// 꺠고 넘기기
for (i in 0 until n) {
// now 자신
if (i == now) continue
// 이미 깨진 계란
if (heart[i] <= 0) continue
// 계란 부딪히기
val _heart = heart.toMutableList()
_heart[now] -= weight[i]
_heart[i] -= weight[now]
hit(n, now + 1, _heart, weight)
}
}
eggs[idx][0] += eggs[j][1] | ||
eggs[j][0] += eggs[idx][1] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저는 여기서 돌려주지않고 그냥 매번 새로운 리스트를 생성합니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
매번 새로운 리스트를 생성하면
위와 같이 백트래킹 방식으로 갔다가 다시 되돌려놓으면
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이거 처음 봤을 때 문제 이해가 잘 안돼서 살짝 당황했던 기억이... ㅋㅋ
input = open(0).readline
N = int(input())
S, W = [0] * N, [0] * N
for i in range(N):
s, w = map(int, input().split())
S[i], W[i] = s, w
def backtracking(current: int = 0, broken: int = 0) -> int:
if broken == N - 1 or current == N: # 모든 계란이 깨졌거나 끝까지 왔다면면
return broken
if S[current] <= 0: # 이미 깨짐
return backtracking(current + 1, broken)
count: int = 0
for nxt in range(N):
if current == nxt or S[nxt] <= 0: # 같은 계란이거나 이미 깨졌다면 skip
continue
S[current] -= W[nxt]
S[nxt] -= W[current]
count = max(count, backtracking(current + 1, broken + (S[current] <= 0) + (S[nxt] <= 0)))
S[current] += W[nxt]
S[nxt] += W[current]
return count
print(backtracking())
N = int(input()) | ||
eggs = [list(map(int, input().split())) for _ in range(N)] | ||
|
||
def break_egg(idx): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
백트래킹 함수의 인자로 "계란을 몇 개 깼는가" 정보를 같이 넘겨주게 되면 조금 더 효율적으로 동작하게 만들 수 있습니다
def backtracking(current: int = 0, broken: int = 0) -> int:
if broken == N - 1 or current == N: # 모든 계란이 깨졌거나 끝까지 왔다면
return broken
if S[current] <= 0: # 이미 깨짐
return backtracking(current + 1, broken)
count: int = 0
for nxt in range(N):
if current == nxt or S[nxt] <= 0: # 같은 계란이거나 이미 깨졌다면 skip
continue
S[current] -= W[nxt]
S[nxt] -= W[current]
count = max(count, backtracking(current + 1, broken + (S[current] <= 0) + (S[nxt] <= 0)))
S[current] += W[nxt]
S[nxt] += W[current]
return count
broken 인자를 들고 있기 때문에 리스트를 순회해서 깨진 계란 개수를 카운팅하는 과정 자체가 사라집니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
제 코드의 경우엔 재귀 제한을 안풀어줘도 되더라구요 :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
N이 최대 8이라는 점에서
8^8의 시간 복잡도가 최대
즉,
백트래킹으로 쌉가능이라고 판단하구 풀었씁니다 히히히
변수 되돌리는 부분에서 좀 귀찮았는데 원큐에 빵야! 하고 풀어서 재밌었씁니둥
import sys
def input(): return sys.stdin.readline().rstrip()
N = int(input())
eggs = []
is_broken = [False for _ in range(N)]
for _ in range(N):
durability, weight = map(int, input().split())
eggs.append([durability, weight])
answer = 0
def dfs(eggs, is_borken, depth):
global answer
if depth == len(eggs):
answer = max(answer, sum(is_borken))
return
if is_borken[depth]:
dfs(eggs, is_borken, depth+1)
return
can_hit = False
now_egg = eggs[depth]
now_durability, now_weight = now_egg[0], now_egg[1]
for poor_idx in range(N):
if poor_idx == depth: continue
if is_borken[poor_idx]: continue
can_hit = True
poor_egg = eggs[poor_idx]
poor_durability, poor_weight = poor_egg[0], poor_egg[1]
new_now_durability = now_durability - poor_weight
new_poor_durability = poor_durability - now_weight
if new_now_durability <= 0: is_borken[depth] = True
if new_poor_durability <= 0: is_borken[poor_idx] = True
eggs[depth], eggs[poor_idx] = [new_now_durability, now_weight], [new_poor_durability, poor_weight]
dfs(eggs, is_borken, depth+1)
eggs[depth], eggs[poor_idx] = [now_durability, now_weight], [poor_durability, poor_weight]
is_borken[depth] = False
is_borken[poor_idx] = False
if can_hit == False: answer = max(answer, sum(is_borken))
return
dfs(eggs, is_broken, 0)
print(answer)
헉 멍청하게 가장 왼쪽에 먼저 들고 아무거나 치는 것인데 생각을 잘못해서 3 가 왜 2인가.. 생각하고 있었는데 문해력 이슈가 일어났군요.. 이해하고 아래와 같이 풀었습니다! def egg_crack(index, eggs):
if index == len(eggs):
return sum(1 for durability, _ in eggs if durability <= 0)
if eggs[index][0] <= 0:
# 현재 계란 깨졋으면 다음 계란
return egg_crack(index + 1, eggs)
max_broken = 0
hit = False # 다른 계란 쳤는지
for i in range(len(eggs)):
if i != index and eggs[i][0] > 0:
hit = True
eggs[index][0] -= eggs[i][1]
eggs[i][0] -= eggs[index][1]
max_broken = max(max_broken, egg_crack(index + 1, eggs))
eggs[index][0] += eggs[i][1]
eggs[i][0] += eggs[index][1]
# 칠 수 있는 계란이 없으면 다음 계란으로 넘어감
if not hit:
max_broken = max(max_broken, egg_crack(index + 1, eggs))
return max_broken
n = int(input())
egg = [list(map(int, input().split())) for _ in range(n)]
print(egg_crack(0, egg)) |
for j in range(N): # 계란 깨기 | ||
if j != idx and eggs[j][0] > 0: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
따로 사소한 궁금점인데...
혹시 j로 반복문을 돌리신 이유가 있으실까요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
음 왜 j냐고 물으신다면 .... i 다음에 j 쓰는게 습관이어요
큰 의미는 없슴다!
🔗 문제 링크
계란으로 계란치기
✔️ 소요된 시간
✨ 수도 코드
사실 저번 PR 때 쓰려다가 못풀어서 이번 PR로 들고 왔습니다
문제요약
다음 과정을 거쳐 깰 수 있는 최대 계란 수를 반환하라 @!
수도 코드는 간단합니다
문제를 풀 때 주의할 점은,
계란을 깨는 과정이 백트래킹이기 때문에 다시 깼던 계란을 다시 돌려주는 것입니다.
eggs[idx]계란으로 자기 자신을 제외한 eggs[0]~eggs[N-1]을 깹니다. 다음 계란으로 넘어가기 전에 재귀를 해주고, 깨지기 이전 상태로 돌려주어야 합니다.
저는 이 부분에서 다른 레퍼런스를 참고했습니다
📚 새롭게 알게된 내용