[Leetcode] 2861. Maximum Number of Alloys

이강혁·2024년 6월 15일
0

leetcode

목록 보기
2/17

https://leetcode.com/problems/maximum-number-of-alloys/description/

기계가 여럿있고 기계마다 합금 제작을 위해 필요한 재료가 다르고, 재료별 재고와 비용 그리고 예산이 주어진 상태에서 합금을 가장 많이 만들라고 한다.

처음에는 2중 for문으로 돌리면서 기계별로 예산 써서 최대로 뽑아낼 수 있는 합금의 양을 다 계산한 후에 최대값을 고르는 방식을 사용하려고 했다.

class Solution:
    def maxNumberOfAlloys(self, n: int, k: int, budget: int, composition: List[List[int]], stock: List[int], cost: List[int]) -> int:
        # index 1부터 시작함
        # binary search
        
        answer = 0
        for c in composition:
            answer = max(answer, createAlloy(c, stock.copy(), budget, cost))
        return answer

def createAlloy(machine, stock, budget, cost):
    count = 0

    while True:
        chk = True
        for i in range(len(stock)):
            while stock[i] < machine[i]:
                budget -= cost[i]
                stock[i] += 1
            
            if budget < 0:
                chk = False
                break

            stock[i] -= machine[i]
         
        if chk:
            count += 1
        else:
            break
    return count

그리고 시간초과가 났다.

만들려고 하는 합금의 수를 변수로 두고 바이너리 서치로 전환했다. 기계별로 binary search를 통해서 최대로 만들 수 있는 합금을 계산했다. 최대치를 계산할 때는 mid로 먼저 기계에 할당하고 예산이 부족한지, 남는지에 따라서 mid를 조정했고 최대값을 만들었다. 계산할 때마다 전체의 최대값을 갱신했고 그게 정답이 되었다.

class Solution:
    def maxNumberOfAlloys(self, n: int, k: int, budget: int, composition: List[List[int]], stock: List[int], cost: List[int]) -> int:
        # 만들 수 있는 합금의 최대값
        # 기계를 선택하면 결과는 알아서 나옴

        # 개수를 기준으로 budget을 넘지않은 채로 합금 만들 수 있는 기계를 찾아야하나?
        # binary search 100번
        answer = 0


        for c in composition:
            tmp = 0
            start = 0
            end = 1000000000

            while start <= end:
                mid = (start + end) // 2

                over = createAlloy(c, stock, cost, mid)
                print(c, mid, over)

                if over > budget:
                    end = mid - 1
                else:
                    tmp = mid
                    start = mid + 1
            print(c, tmp)
            answer = max(answer, tmp)
        return answer
            

            

def createAlloy(machine, stock, cost, order):
    totalcost = 0
    
    for i in range(len(machine)):
        # 추가 구매 비용은 이만큼
        if stock[i] < machine[i] * order:
            totalcost += cost[i] * (machine[i] * order - stock[i])

    return totalcost

최초에 이 코드로 돌렸을 때 시간초과는 안 났으나 두 번 실패했다. binary search할 때 사용하는 end값이 너무 작아서 발생한 문제였다. end값을 재고의 최대 + 예산의 최대로 계산해서 하면 될 것 같았는데 문제 풀 당시에는 생각이 안나서 그냥 0을 계속 붙여줬다.

profile
사용자불량

0개의 댓글