[python]๋ฐฑ์ค€ 6549๋ฒˆ : ํžˆ์Šคํ† ๊ทธ๋žจ์—์„œ ๊ฐ€์žฅ ํฐ ์ง์‚ฌ๊ฐํ˜•

์‹œ๊ฐ„ ์ œํ•œ ๋ฉ”๋ชจ๋ฆฌ ์ œํ•œ ์ œ์ถœ ์ •๋‹ต ๋งž์€ ์‚ฌ๋žŒ ์ •๋‹ต ๋น„์œจ
1 ์ดˆ 256 MB 16367 3904 2522 25.125%

๋ฌธ์ œ

ํžˆ์Šคํ† ๊ทธ๋žจ์€ ์ง์‚ฌ๊ฐํ˜• ์—ฌ๋Ÿฌ ๊ฐœ๊ฐ€ ์•„๋ž˜์ชฝ์œผ๋กœ ์ •๋ ฌ๋˜์–ด ์žˆ๋Š” ๋„ํ˜•์ด๋‹ค. ๊ฐ ์ง์‚ฌ๊ฐํ˜•์€ ๊ฐ™์€ ๋„ˆ๋น„๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€๋งŒ, ๋†’์ด๋Š” ์„œ๋กœ ๋‹ค๋ฅผ ์ˆ˜๋„ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์™ผ์ชฝ ๊ทธ๋ฆผ์€ ๋†’์ด๊ฐ€ 2, 1, 4, 5, 1, 3, 3์ด๊ณ  ๋„ˆ๋น„๊ฐ€ 1์ธ ์ง์‚ฌ๊ฐํ˜•์œผ๋กœ ์ด๋ฃจ์–ด์ง„ ํžˆ์Šคํ† ๊ทธ๋žจ์ด๋‹ค.

img

ํžˆ์Šคํ† ๊ทธ๋žจ์—์„œ ๊ฐ€์žฅ ๋„“์ด๊ฐ€ ํฐ ์ง์‚ฌ๊ฐํ˜•์„ ๊ตฌํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•˜์‹œ์˜ค.

์ž…๋ ฅ

์ž…๋ ฅ์€ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์—ฌ๋Ÿฌ ๊ฐœ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค. ๊ฐ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋Š” ํ•œ ์ค„๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๊ณ , ์ง์‚ฌ๊ฐํ˜•์˜ ์ˆ˜ n์ด ๊ฐ€์žฅ ์ฒ˜์Œ์œผ๋กœ ์ฃผ์–ด์ง„๋‹ค. (1 ≤ n ≤ 100,000) ๊ทธ ๋‹ค์Œ n๊ฐœ์˜ ์ •์ˆ˜ h1, ..., hn (0 ≤ hi ≤ 1,000,000,000)๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. ์ด ์ˆซ์ž๋“ค์€ ํžˆ์Šคํ† ๊ทธ๋žจ์— ์žˆ๋Š” ์ง์‚ฌ๊ฐํ˜•์˜ ๋†’์ด์ด๋ฉฐ, ์™ผ์ชฝ๋ถ€ํ„ฐ ์˜ค๋ฅธ์ชฝ๊นŒ์ง€ ์ˆœ์„œ๋Œ€๋กœ ์ฃผ์–ด์ง„๋‹ค. ๋ชจ๋“  ์ง์‚ฌ๊ฐํ˜•์˜ ๋„ˆ๋น„๋Š” 1์ด๊ณ , ์ž…๋ ฅ์˜ ๋งˆ์ง€๋ง‰ ์ค„์—๋Š” 0์ด ํ•˜๋‚˜ ์ฃผ์–ด์ง„๋‹ค.

์ถœ๋ ฅ

๊ฐ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์— ๋Œ€ํ•ด์„œ, ํžˆ์Šคํ† ๊ทธ๋žจ์—์„œ ๊ฐ€์žฅ ๋„“์ด๊ฐ€ ํฐ ์ง์‚ฌ๊ฐํ˜•์˜ ๋„“์ด๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.

๋‚˜์˜ ๋‹ต

์ฒซ๋ฒˆ์งธ ์ฝ”๋“œ

def calArea(dic):
    max_result = 0
    print(dic)
    for key in dic:
        for obj in dic[key]:
            if obj*key>max_result:
                max_result=obj*key
    return max_result

def calMaxArea(l,h):
    min = h[0]
    tmp_dic = dict()
    tmp_dic[min]=[1]
    index = 1
    arr = list()
    arr.append(min)
    past_renew = list()

    for i in range(0,l-1):
        past_renew = list(set(arr)) #์ค‘๋ณต ์—†์• ๊ธฐ
        arr = []
        if h[i]>=h[i+1]: # ์•ž์ด ๋’ค๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์€ ๊ฒฝ์šฐ
            if h[i+1] in past_renew:
                tmp_dic[h[i+1]].append(tmp_dic[h[i+1]].pop()+1)
            elif h[i+1] in tmp_dic.keys():
                tmp_dic[h[i+1]].append(2)
            else:
                tmp_dic[h[i+1]]=[2]

            arr.append(h[i+1])
            if h[i+1] in past_renew:
                past_renew.remove(h[i+1])

            if min>h[i+1]: # min ๊ฐฑ์‹ 
                min = h[i+1]
                if min in tmp_dic.keys():
                    tmp_dic[min].append(index)
                else:
                    tmp_dic[min]=[index]

        else: # ๋’ค๊ฐ€ ๋” ํฐ ๊ฒฝ์šฐ
            if h[i+1] in tmp_dic.keys():
                tmp_dic[h[i+1]].append(1)
            else:
                tmp_dic[h[i+1]]=[1]

            if h[i] in past_renew:
                tmp_dic[h[i]].append(tmp_dic[h[i]].pop()+1)
            elif h[i] in tmp_dic.keys():
                tmp_dic[h[i]].append(2)
            else:
                tmp_dic[h[i]]=[2]

            arr.append(h[i])
            arr.append(h[i+1])
            if h[i] in past_renew:
                past_renew.remove(h[i])
            if h[i+1] in past_renew:
                past_renew.remove(h[i+1])

        index+=1
        tmp_dic[min].pop()
        tmp_dic[min].append(index)
        arr.append(min)
        if min in past_renew:
            past_renew.remove(min)

        for obj in past_renew:
            if obj <= h[i+1]:
                if len(tmp_dic[obj])>=2: # ์ €์žฅ๋œ value๊ฐ€ 2๊ฐœ ์ด์ƒ์ด๋ฉด
                    tmp_dic[obj].append(tmp_dic[obj].pop()+1)
                else:
                    tmp_dic[obj]=[tmp_dic[obj].pop()+1]
                arr.append(obj)

    return calArea(tmp_dic)



result = list()
while(1):
    tmp = list(map(int,input().split()))
    length = tmp[0]
    if not(length):
        break
    height = tmp[1:]
    result.append(calMaxArea(length,height))

for res in result:
    print(res)

์‹œ๊ฐ„ ์ดˆ๊ณผ

๋‚ด๊ฐ€ ์ƒ๊ฐํ•ด๋„ ๋„ˆ๋ฌด ๋ณต์žกํ•˜๊ฒŒ ์ง  ์ฝ”๋“œ๋ผ ์„ค๋ช…์กฐ์ฐจ ๋ชปํ•˜๊ฒ ๋‹ค..

๋‘๋ฒˆ์งธ ์ฝ”๋“œ

def calMaxArea():
    global height
    global area
    if len(height)==1: # ๊ธฐ์ €์‚ฌ๋ก€
        if height[0]>area:
            return height[0]
        else:
            return area

    # ๊ฐ€์žฅ ์ž‘์€ ์ˆ˜๋ฅผ ๋ฐ›์•„์„œ
    min_height = min(height) # O(h)
    min_index = height.index(min_height)

    cal_area = min_height*len(height) 
    if cal_area>area: # ๋” ํฐ ๊ฐ’์ด ๋‚˜์˜ค๋ฉด ๊ฐฑ์‹ 
        area = cal_area


    # ๊ฐ€์žฅ ์ž‘์€ ๋†’์ด๊ฐ€ ์–‘๋์— ์œ„์น˜ํ•˜๋ฉด
    if min_index ==0 or min_index == len(height)-1:
        del height[min_index]
        return calMaxArea()
    else:
        tmp_height = height[min_index+1:]
        height = height[:min_index]
        t1 = calMaxArea()
        height = tmp_height
        t2 = calMaxArea()
        if t1>t2:
            return t1
        else:
            return t2

    # ์ตœ๋Œ€ 2log(n)๋ฒˆ
    # ์ด O(hlog(n))

result = list()
while(1):
    tmp = list(map(int,input().split()))
    length = tmp[0]
    if not(length):
        break
    height = tmp[1:]
    area = 0
    result.append(calMaxArea())

for res in result:
    print(res)

๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ณผ

๋ถ„ํ•  ์ •๋ณต์„ ์‚ฌ์šฉํ•˜์˜€๋‹ค.

O(hlogn)์ด ๋‚˜์˜ค๋Š”๋ฐ์—์„œ h์˜ ๋ฒ”์œ„๊ฐ€ ๋„ˆ๋ฌด ํฐ ์ˆ˜์ด๋ฏ€๋กœ O(h)๊ฐ€ ๋‚˜์˜ค๋Š” min์„ ๊ฐœ์„ ํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค. min์€ python ๊ธฐ๋ณธ ์—ฐ์‚ฐ์ž๋กœ O(n)์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ์ตœ์†Œ๋ฅผ ์ฐพ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ค‘ O(n) ์ดํ•˜์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋ฅผ ๊ฐ€์ง„ '์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ' ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์žˆ๋‹ค.

https://www.acmicpc.net/blog/view/9

๋‹ค๋ฅธ ๋‹ต

๊ฒฐ๊ตญ ๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ณผ๊ฐ€ ๋‚˜์™€์„œ ์ •๋‹ต ์ฝ”๋“œ๋ฅผ ์ฐพ์•„๋ณด์•˜๋”๋‹ˆ https://joosjuliet.github.io/6549/ ์ด ๊ณณ์—์„œ ๋‹จ 10์ค„ ์ •๋„๋กœ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ๊ฐ€ ์žˆ์—ˆ๋‹ค ใ… .. ๋Œ€๋‹จํ•˜๋‹ค. ๋ผ์ธ ์Šค์œ„ํ•‘ + ์Šคํƒ ์ž๋ฃŒ๊ตฌ์กฐ ๋ฅผ ์ด์šฉํ•ด์„œ ํ’€์—ˆ๋‹ค. ๋ฐฉ๋ฒ•์€ ๋ณธ์ธ๊ณผ ๋น„์Šทํ•œ ๊ฒƒ ๊ฐ™์€๋ฐ ํ›จ์”ฌ ํŒŒ์ด์ฌ์ด๋ผ๋Š” ์–ธ์–ด์— ๋Œ€ํ•œ ์ดํ•ด๋„๊ฐ€ ๊นŠ์€ ๊ฒƒ ๊ฐ™์•˜๋‹ค. ์•„๋ž˜์˜ ๊ทธ๋ฆผ์€ ์ด ๋ธ”๋กœ๊ทธ์˜ ์ฝ”๋“œ๋ฅผ ์ฝ๊ณ  ์ดํ•ดํ•œ ๋Œ€๋กœ ๊ทธ๋ ค๋ณธ ๊ฒƒ์ด๋‹ค.

=> ์Šคํƒ ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ํŽธํ•จ

๋˜ํ•œ ์ด ๋ฐฉ๋ฒ• ๋ง๊ณ ๋„ ๋ฐฑ์ค€ ๋ธ”๋กœ๊ทธ์—์„œ ์ถ”์ฒœํ•œ ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ + ๋ถ„ํ• ์ •๋ณต ์ด๋‚˜ ์„ธ๊ทธ๋จผํŠธ ํŠธ๋ฆฌ + ๋ผ์ธ์Šค์œ„ํ•‘ ๋ฐฉ๋ฒ•๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

import math

def init(node, start, end):
    global tree_list
    global height
    if start == end:
        tree_list[node-1] = start
    else:
        init(node*2,start,(start+end)//2)
        init(node*2+1,(start+end)//2+1,end)
        if height[tree_list[node*2-1]]<height[tree_list[node*2]]:
            tree_list[node-1] = tree_list[node*2-1]
        else:
            tree_list[node-1] = tree_list[node*2]

def query(node,start,end,i,j):
    global tree_list
    global height
    if i>end or j<start: # ์ฃผ์–ด์ง„ ๋ฒ”์œ„๊ฐ€ ์ „์ฒด ๋ฒ”์œ„์— ์™„์ „ํžˆ ์†ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด
        return -1 
    if i<=start and end<=j: # ์ฃผ์–ด์ง„ ๋ฒ”์œ„๊ฐ€ ์ „์ฒด ๋ฒ”์œ„๋ฅผ ์™„์ „ํžˆ ํฌํ•จํ•œ๋‹ค๋ฉด
        return tree_list[node-1] # ํ•ด๋‹น ๋ฒ”์œ„์˜ ์ตœ์†Œ๊ฐ’ index๋ฅผ return ํ•จ

    # ์ฃผ์–ด์ง„ ๋ฒ”์œ„๊ฐ€ ์ „์ฒด ๋ฒ”์œ„์— ์†ํ•ด์žˆ๋‹ค๋ฉด
    # ex_) 0~4 index์˜ ๊ฐ’์ด ์ฃผ์–ด์กŒ์„ ๋•Œ, 1~3 index์— ๋Œ€ํ•œ ์ตœ์†Œ๊ฐ’์„ ๊ตฌํ•˜๊ณ  ์‹ถ์Œ
    m1 = query(2*node,start,(start+end)//2,i,j) # ์ „์ฒด ๋ฒ”์œ„๋ฅผ ๋ฐ˜์œผ๋กœ ์ž๋ฅธ ๋ฒ”์œ„๋ฅผ ๋„˜๊ธฐ๊ณ  ์™ผ์ชฝ ๋…ธ๋“œ ๊ฐ’์„ ๋„˜๊น€
    m2 = query(2*node+1,(start+end)//2+1,end,i,j) # ์ „์ฒด ๋ฒ”์œ„๋ฅผ ๋ฐ˜์œผ๋กœ ์ž๋ฅธ ๋ฒ”์œ„๋ฅผ ๋„˜๊ธฐ๊ณ  ์˜ค๋ฅธ์ชฝ ๋…ธ๋“œ ๊ฐ’์„ ๋„˜๊น€
    if m1==-1:
        return m2
    elif m2==-1:
        return m1
    else:
        if height[m1]<=height[m2]:
            return m1
        else:
            return m2


def maxArea(start, end):
    global tree_list
    global height
    min_index = query(1,0,len(height)-1,start,end)
    area = (end-start+1)*height[min_index]
    if min_index-1>=start:
        tmp = maxArea(start,min_index-1)
        if tmp>area:
            area = tmp
    if min_index+1<=end:
        tmp = maxArea(min_index+1,end)
        if tmp>area:
            area = tmp

    return area



result = list()
while(1):
    input_list = list(map(int,input().split()))
    n = input_list[0]
    if n==0:
        break
    height = input_list[1:]
    tree_list = [0]*(pow(2,math.ceil(math.log(len(height),2))+1)-1)
    init(1,0,n-1)
    result.append(maxArea(0,n-1))
    del tree_list

for obj in result:
    print(obj)

๊ตฌํ˜„ํ•ด๋ณด์•˜์ง€๋งŒ ๊ณ„์† ๋Ÿฐํƒ€์ž„์˜ค๋ฅ˜๊ฐ€ ๋‚œ๋‹ค. ์ด์œ ๋Š” long ํƒ€์ž…์œผ๋กœ ๊ตฌ์„ฑํ•˜์ง€ ์•Š์•„์„œ ์ธ ๊ฒƒ ๊ฐ™์€๋ฐ, python์€ ์• ์ดˆ์— ๋ฒ”์œ„๊ฐ€ intํ˜•์„ ์ดˆ๊ณผํ•˜๋ฉด ์ž๋™์œผ๋กœ longํ˜•์œผ๋กœ ๋ณ€ํ™˜๋œ๋‹ค๊ณ  ํ•œ๋‹ค. ๋˜ํ•œ, long ํ˜•์˜ ๊ฐ•์ œ์  ํ˜•๋ณ€ํ™˜์ด ๋ฌด์Šจ ์ด์œ ์—์„œ์ธ์ง€ ๋จนํžˆ์ง€ ์•Š๋Š”๋‹ค. ใ… ใ… 

๋ฐ˜์‘ํ˜•