<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>시간 복잡도 Archives - 어제와 내일의 나 그 사이의 이야기</title>
	<atom:link href="https://lycos7560.com/tag/%EC%8B%9C%EA%B0%84-%EB%B3%B5%EC%9E%A1%EB%8F%84/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>생각의 흐름을 타고 다니며 만드는 블로그</description>
	<lastBuildDate>Mon, 13 Oct 2025 06:07:16 +0000</lastBuildDate>
	<language>ko-KR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://lycos7560.com/wp-content/uploads/2022/11/cropped-cropped-cropped-log-1-150x150-1-80x80.png</url>
	<title>시간 복잡도 Archives - 어제와 내일의 나 그 사이의 이야기</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>백준 14003번 (가장 긴 증가하는 부분 수열 5, C++)</title>
		<link>https://lycos7560.com/cpp/%eb%b0%b1%ec%a4%80-14003%eb%b2%88-%ea%b0%80%ec%9e%a5-%ea%b8%b4-%ec%a6%9d%ea%b0%80%ed%95%98%eb%8a%94-%eb%b6%80%eb%b6%84-%ec%88%98%ec%97%b4-5-c/40314/</link>
					<comments>https://lycos7560.com/cpp/%eb%b0%b1%ec%a4%80-14003%eb%b2%88-%ea%b0%80%ec%9e%a5-%ea%b8%b4-%ec%a6%9d%ea%b0%80%ed%95%98%eb%8a%94-%eb%b6%80%eb%b6%84-%ec%88%98%ec%97%b4-5-c/40314/#comments</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Mon, 13 Oct 2025 06:06:17 +0000</pubDate>
				<category><![CDATA[BaekjoonOnlineJudge]]></category>
		<category><![CDATA[C++/CPP]]></category>
		<category><![CDATA[14003]]></category>
		<category><![CDATA[14003번]]></category>
		<category><![CDATA[algorithm]]></category>
		<category><![CDATA[Algorithm Analysis]]></category>
		<category><![CDATA[Algorithm Explanation]]></category>
		<category><![CDATA[Algorithm Practice]]></category>
		<category><![CDATA[Algorithm Study]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[Baekjoon]]></category>
		<category><![CDATA[Binary Search]]></category>
		<category><![CDATA[Binary Search LIS]]></category>
		<category><![CDATA[binary_search]]></category>
		<category><![CDATA[BOJ 14003]]></category>
		<category><![CDATA[BOJ Solution]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[C++ Algorithm]]></category>
		<category><![CDATA[C++ STL]]></category>
		<category><![CDATA[Coding Interview]]></category>
		<category><![CDATA[Coding Lecture]]></category>
		<category><![CDATA[Coding Test]]></category>
		<category><![CDATA[Competitive Coding]]></category>
		<category><![CDATA[Competitive Programming]]></category>
		<category><![CDATA[cpp]]></category>
		<category><![CDATA[Data Structure]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[DP]]></category>
		<category><![CDATA[DP Table]]></category>
		<category><![CDATA[Dynamic Programming]]></category>
		<category><![CDATA[Efficiency]]></category>
		<category><![CDATA[Example Walkthrough]]></category>
		<category><![CDATA[Fast IO]]></category>
		<category><![CDATA[Greedy]]></category>
		<category><![CDATA[Greedy Algorithm]]></category>
		<category><![CDATA[Implementation]]></category>
		<category><![CDATA[Increasing Sequence]]></category>
		<category><![CDATA[Index Mapping]]></category>
		<category><![CDATA[Index Tracking]]></category>
		<category><![CDATA[Input Output]]></category>
		<category><![CDATA[LIS]]></category>
		<category><![CDATA[LIS Diagram]]></category>
		<category><![CDATA[LIS Example]]></category>
		<category><![CDATA[LIS Flow]]></category>
		<category><![CDATA[LIS Indexing]]></category>
		<category><![CDATA[LIS Pattern]]></category>
		<category><![CDATA[LIS Reconstruction]]></category>
		<category><![CDATA[LIS Reconstruction Algorithm]]></category>
		<category><![CDATA[LIS step by step]]></category>
		<category><![CDATA[LIS Study]]></category>
		<category><![CDATA[LIS Table]]></category>
		<category><![CDATA[LIS Tail]]></category>
		<category><![CDATA[LIS Track]]></category>
		<category><![CDATA[LIS Tutorial]]></category>
		<category><![CDATA[LIS using Binary Search]]></category>
		<category><![CDATA[LIS Visualization]]></category>
		<category><![CDATA[LIS 강의]]></category>
		<category><![CDATA[LIS 구현]]></category>
		<category><![CDATA[LIS 단계별]]></category>
		<category><![CDATA[LIS 문제]]></category>
		<category><![CDATA[LIS 문제풀이]]></category>
		<category><![CDATA[LIS 복원]]></category>
		<category><![CDATA[LIS 복원 알고리즘]]></category>
		<category><![CDATA[LIS 알고리즘]]></category>
		<category><![CDATA[LIS 예제]]></category>
		<category><![CDATA[LIS 추적]]></category>
		<category><![CDATA[LIS 코드]]></category>
		<category><![CDATA[LIS 패턴]]></category>
		<category><![CDATA[Logic Explanation]]></category>
		<category><![CDATA[Longest Increasing Subsequence]]></category>
		<category><![CDATA[Longest Subsequence]]></category>
		<category><![CDATA[lower_bound]]></category>
		<category><![CDATA[Memory Limit]]></category>
		<category><![CDATA[Memory Optimization]]></category>
		<category><![CDATA[O(N log N)]]></category>
		<category><![CDATA[O(N^2)]]></category>
		<category><![CDATA[O(NlogN)]]></category>
		<category><![CDATA[Optimal Algorithm]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[Prev Index]]></category>
		<category><![CDATA[Problem Explanation]]></category>
		<category><![CDATA[problem solving]]></category>
		<category><![CDATA[Programming Algorithm]]></category>
		<category><![CDATA[Programming Study]]></category>
		<category><![CDATA[Sequence Analysis]]></category>
		<category><![CDATA[Sequence Optimization]]></category>
		<category><![CDATA[Sequence Problem]]></category>
		<category><![CDATA[Sequence Reconstruction]]></category>
		<category><![CDATA[Sequence Trace]]></category>
		<category><![CDATA[STL]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[Subsequence]]></category>
		<category><![CDATA[Tail Array]]></category>
		<category><![CDATA[Theory]]></category>
		<category><![CDATA[Time Complexity]]></category>
		<category><![CDATA[Time Limit]]></category>
		<category><![CDATA[Traceback]]></category>
		<category><![CDATA[upper_bound]]></category>
		<category><![CDATA[vector]]></category>
		<category><![CDATA[가장 긴 증가하는 부분 수열]]></category>
		<category><![CDATA[가장 긴 증가하는 부분 수열 5]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[동적 계획법]]></category>
		<category><![CDATA[디버깅]]></category>
		<category><![CDATA[로직 해설]]></category>
		<category><![CDATA[메모리 최적화]]></category>
		<category><![CDATA[문제 해설]]></category>
		<category><![CDATA[배열]]></category>
		<category><![CDATA[백준]]></category>
		<category><![CDATA[백준 14003]]></category>
		<category><![CDATA[백준 14003번]]></category>
		<category><![CDATA[백준 문제풀이]]></category>
		<category><![CDATA[벡터]]></category>
		<category><![CDATA[수열 문제]]></category>
		<category><![CDATA[수열 분석]]></category>
		<category><![CDATA[수열 추적]]></category>
		<category><![CDATA[시간 복잡도]]></category>
		<category><![CDATA[시간 제한]]></category>
		<category><![CDATA[시간 최적화]]></category>
		<category><![CDATA[알고리즘]]></category>
		<category><![CDATA[알고리즘 분석]]></category>
		<category><![CDATA[알고리즘 설명]]></category>
		<category><![CDATA[알고리즘 연습]]></category>
		<category><![CDATA[예제 해설]]></category>
		<category><![CDATA[이론]]></category>
		<category><![CDATA[이분 탐색]]></category>
		<category><![CDATA[인덱스 기반 LIS]]></category>
		<category><![CDATA[입출력]]></category>
		<category><![CDATA[자료구조]]></category>
		<category><![CDATA[증가 수열]]></category>
		<category><![CDATA[최장 부분 수열]]></category>
		<category><![CDATA[최적화]]></category>
		<category><![CDATA[최적화 알고리즘]]></category>
		<category><![CDATA[추적]]></category>
		<category><![CDATA[코딩 강의]]></category>
		<category><![CDATA[코딩 공부]]></category>
		<category><![CDATA[코딩 인터뷰]]></category>
		<category><![CDATA[코딩테스트]]></category>
		<category><![CDATA[코테]]></category>
		<category><![CDATA[탐욕 알고리즘]]></category>
		<category><![CDATA[효율성]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40314</guid>

					<description><![CDATA[<p>가장 긴 증가하는 부분 수열 5 https://www.acmicpc.net/problem/14003 시간 제한 메모리 제한 제출 정답 맞힌 사람 정답 비율 3 초 512 MB 45574 15974 11322 34.533% 문제 수열 A가 주어졌을 때, 가장 긴 증가하는&#160;부분&#160;수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분&#160;수열은&#160;A = {10,&#160;20, [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/cpp/%eb%b0%b1%ec%a4%80-14003%eb%b2%88-%ea%b0%80%ec%9e%a5-%ea%b8%b4-%ec%a6%9d%ea%b0%80%ed%95%98%eb%8a%94-%eb%b6%80%eb%b6%84-%ec%88%98%ec%97%b4-5-c/40314/">백준 14003번 (가장 긴 증가하는 부분 수열 5, C++)</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-87ca5ab3      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#가장-긴-증가하는-부분-수열-5" class="uagb-toc-link__trigger">가장 긴 증가하는 부분 수열 5</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#문제" class="uagb-toc-link__trigger">문제</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#입력" class="uagb-toc-link__trigger">입력</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#출력" class="uagb-toc-link__trigger">출력</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#예제-입력-1" class="uagb-toc-link__trigger">예제 입력 1</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#예제-출력-1" class="uagb-toc-link__trigger">예제 출력 1</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#출처" class="uagb-toc-link__trigger">출처</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#비슷한-문제" class="uagb-toc-link__trigger">비슷한 문제</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#알고리즘-분류" class="uagb-toc-link__trigger">알고리즘 분류</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1차-시도-로직-그대로-구현" class="uagb-toc-link__trigger">1차 시도 &#8211; 로직 그대로 구현</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2차-시도-이분-탐색-인덱스-추적을-이용한-lis-복원-on-log-n" class="uagb-toc-link__trigger">2차 시도 &#8211; 이분 탐색 + 인덱스 추적을 이용한 LIS 복원 / O(N log N)</a></ul></ol>					</div>
									</div>
				</div>
			


<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">가장 긴 증가하는 부분 수열 5 <img decoding="async" width="35" height="45" class="wp-image-37909" style="width: 35px;" src="https://lycos7560.com/wp-content/uploads/2024/03/Platinum_5.jpg" alt="" srcset="https://lycos7560.com/wp-content/uploads/2024/03/Platinum_5.jpg 400w, https://lycos7560.com/wp-content/uploads/2024/03/Platinum_5-234x300.jpg 234w" sizes="(max-width: 35px) 100vw, 35px" /></h2>



<p class="wp-block-paragraph"><a href="https://www.acmicpc.net/problem/14003" target="_blank" rel="noreferrer noopener">https://www.acmicpc.net/problem/14003</a></p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>시간 제한</th><th>메모리 제한</th><th>제출</th><th>정답</th><th>맞힌 사람</th><th>정답 비율</th></tr></thead><tbody><tr><td>3 초</td><td>512 MB</td><td>45574</td><td>15974</td><td>11322</td><td>34.533%</td></tr></tbody></table></figure>



<h3 class="wp-block-heading">문제</h3>



<p class="wp-block-paragraph">수열 A가 주어졌을 때, 가장 긴 증가하는&nbsp;부분&nbsp;수열을 구하는 프로그램을 작성하시오.</p>



<p class="wp-block-paragraph">예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분&nbsp;수열은&nbsp;A = {<strong>10</strong>,&nbsp;<strong>20</strong>, 10,&nbsp;<strong>30</strong>, 20,&nbsp;<strong>50</strong>} 이고, 길이는 4이다.</p>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">입력</h3>



<p class="wp-block-paragraph">첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다.</p>



<p class="wp-block-paragraph">둘째 줄에는 수열 A를 이루고 있는 A<sub>i</sub>가 주어진다. (-1,000,000,000&nbsp;≤ A<sub>i</sub>&nbsp;≤ 1,000,000,000)</p>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">출력</h3>



<p class="wp-block-paragraph">첫째 줄에 수열 A의 가장 긴 증가하는 부분 수열의 길이를 출력한다.</p>



<p class="wp-block-paragraph">둘째 줄에는 정답이 될 수 있는 가장 긴 증가하는 부분 수열을 출력한다.</p>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<div class="wp-block-uagb-container uagb-block-aa78ee06 alignfull uagb-is-root-container"><div class="uagb-container-inner-blocks-wrap">
<div class="wp-block-uagb-container uagb-block-70c24c24">
<h3 class="wp-block-heading">예제 입력 1</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">6
10 20 10 30 20 50</pre>
</div>



<div class="wp-block-uagb-container uagb-block-2c88bb50">
<h3 class="wp-block-heading">예제 출력 1</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">4
10 20 30 50</pre>
</div>
</div></div>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">출처</h3>



<ul class="wp-block-list">
<li>문제를 만든 사람: <a href="https://www.acmicpc.net/user/baekjoon">baekjoon</a></li>



<li>데이터를 추가한 사람: <a href="https://www.acmicpc.net/user/harinboy">harinboy</a>, <a href="https://www.acmicpc.net/user/jh05013">jh05013</a>, <a href="https://www.acmicpc.net/user/kkw564">kkw564</a>, <a href="https://www.acmicpc.net/user/ldw0318">ldw0318</a>, <a href="https://www.acmicpc.net/user/minho6428">minho6428</a>, <a href="https://www.acmicpc.net/user/sohnryang">sohnryang</a>, <a href="https://www.acmicpc.net/user/surung9898">surung9898</a>, <a href="https://www.acmicpc.net/user/yeo2507">yeo2507</a></li>



<li>빠진 조건을 찾은 사람: <a href="https://www.acmicpc.net/user/Acka">Acka</a></li>
</ul>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">비슷한 문제</h3>



<ul class="wp-block-list">
<li><a href="https://www.acmicpc.net/problem/11053" target="_blank" rel="noreferrer noopener">11053번. 가장 긴 증가하는 부분 수열</a></li>



<li><a href="https://www.acmicpc.net/problem/11054" target="_blank" rel="noreferrer noopener">11054번. 가장 긴 바이토닉 부분 수열</a></li>



<li><a href="https://www.acmicpc.net/problem/11055" target="_blank" rel="noreferrer noopener">11055번. 가장 큰 증가하는 부분 수열</a></li>



<li><a href="https://www.acmicpc.net/problem/11722" target="_blank" rel="noreferrer noopener">11722번. 가장 긴 감소하는 부분 수열</a></li>



<li><a href="https://www.acmicpc.net/problem/12015" target="_blank" rel="noreferrer noopener">12015번. 가장 긴 증가하는 부분 수열 2</a></li>



<li><a href="https://www.acmicpc.net/problem/12738" target="_blank" rel="noreferrer noopener">12738번. 가장 긴 증가하는 부분 수열 3</a></li>



<li><a href="https://www.acmicpc.net/problem/14002" target="_blank" rel="noreferrer noopener">14002번. 가장 긴 증가하는 부분 수열 4</a></li>
</ul>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">알고리즘 분류</h3>



<ul class="wp-block-list">
<li><a href="https://www.acmicpc.net/problem/tag/12" target="_blank" rel="noreferrer noopener">이분 탐색</a></li>



<li><a href="https://www.acmicpc.net/problem/tag/235" target="_blank" rel="noreferrer noopener">역추적</a></li>



<li><a href="https://www.acmicpc.net/problem/tag/43" target="_blank" rel="noreferrer noopener">가장 긴 증가하는 부분 수열 문제</a></li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--60);margin-bottom:var(--wp--preset--spacing--60)"/>



<h3 class="wp-block-heading">1차 시도 &#8211; 로직 그대로 구현</h3>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="1043" height="115" src="https://lycos7560.com/wp-content/uploads/2025/10/image-4.png" alt="" class="wp-image-40317" srcset="https://lycos7560.com/wp-content/uploads/2025/10/image-4.png 1043w, https://lycos7560.com/wp-content/uploads/2025/10/image-4-300x33.png 300w, https://lycos7560.com/wp-content/uploads/2025/10/image-4-768x85.png 768w" sizes="(max-width: 1043px) 100vw, 1043px" /></figure>



<p class="wp-block-paragraph">한 번의 입력(<code>num</code>)에 의해 생성된 새로운 시퀀스들을 임시로 저장</p>



<p class="wp-block-paragraph">어떤 수열에도 붙을 수 없으면 독립된 시퀀스 시작</p>



<p class="wp-block-paragraph">나중에 불필요한 시퀀스(같은 길이인데 꼬리가 큰 것)는 제거</p>



<pre class="EnlighterJSRAW" data-enlighter-language="cpp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#include &lt;iostream>
#include &lt;vector>

using namespace std;

int n; // 수열의 개수
vector&lt;vector&lt;int>> Sequences;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    cin >> n;
    if (n &lt;= 0) return 0;

    int num;
    cin >> num;

    // 첫 번째 수로 초기 시퀀스 하나 생성
    vector&lt;int> sequence;
    sequence.push_back(num);
    Sequences.push_back(sequence);

    for (int i = 1; i &lt; n; i++)
    {
        cin >> num;
        int length = Sequences.size();

        bool canExtend = false;
        vector&lt;vector&lt;int>> newSequences;

        // 기존 시퀀스들을 모두 검사
        for (int j = 0; j &lt; length; j++)
        {
            int last = Sequences[j].back();

            // 확장 가능한 경우 : 새로운 시퀀스 생성
            if (last &lt; num)
            {
                canExtend = true;
                vector&lt;int> extendedSeq = Sequences[j];
                extendedSeq.push_back(num);
                newSequences.push_back(extendedSeq);
            }
        }

        // 어떤 시퀀스에도 붙지 못하면 새로운 시퀀스 시작
        if (!canExtend)
        {
            vector&lt;int> newSeq;
            newSeq.push_back(num);
            newSequences.push_back(newSeq);
        }

        // 새로 생긴 시퀀스들을 기존에 합침
        for (auto&amp; seq : newSequences)
            Sequences.push_back(seq);

        // 최적 시퀀스 길이 및 꼬리값 계산
        int maxSeqSize = 0;
        int bestIndex = 0;
        int bestTail = 1000000001;

        for (int j = 0; j &lt; (int)Sequences.size(); j++)
        {
            int sz = Sequences[j].size();
            int tail = Sequences[j].back();
            if (sz > maxSeqSize || (sz == maxSeqSize &amp;&amp; tail &lt; bestTail))
            {
                maxSeqSize = sz;
                bestTail = tail;
                bestIndex = j;
            }
        }

        // 가지치기: 같은 길이인데 꼬리값이 큰 시퀀스 제거
        for (int j = 0; j &lt; (int)Sequences.size();)
        {
            int sz = Sequences[j].size();
            int tail = Sequences[j].back();

            if (sz == maxSeqSize &amp;&amp; tail > bestTail)
            {
                Sequences.erase(Sequences.begin() + j);
            }
            else
            {
                j++;
            }
        }
    }

	// 결과 중 가장 긴 시퀀스 찾기
    int maxSize = 0;
    int bestIdx = 0;
    for (int i = 0; i &lt; (int)Sequences.size(); i++)
    {
        if (Sequences[i].size() > maxSize)
        {
            maxSize = Sequences[i].size();
            bestIdx = i;
        }
    }

    cout &lt;&lt; maxSize &lt;&lt; "\n";
    for (int x : Sequences[bestIdx])
        cout &lt;&lt; x &lt;&lt; " ";

    return 0;
}
</pre>



<div style="height:25px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">브루트포스 방식으로 모든 가능한 증가 수열을 시도하는 방법은 시간 초과 및 메모리 초과로 인하여 통과할 수 없음.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="604" height="509" src="https://lycos7560.com/wp-content/uploads/2025/10/image-3.png" alt="" class="wp-image-40318" srcset="https://lycos7560.com/wp-content/uploads/2025/10/image-3.png 604w, https://lycos7560.com/wp-content/uploads/2025/10/image-3-300x253.png 300w" sizes="(max-width: 604px) 100vw, 604px" /></figure>



<p class="wp-block-paragraph"><strong>매 반복마다</strong> <code>Sequences</code>의 크기가 <strong>기하급수적으로 늘어나는 구조</strong></p>



<p class="wp-block-paragraph">n개의 원소가 들어오면 2ⁿ에 비례하는 시퀀스로 통과하기 힘들다. (O(2ⁿ))</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>단계</th><th>가능한 Sequences 수</th></tr></thead><tbody><tr><td>1</td><td>[ [1] ]</td></tr><tr><td>2</td><td>[ [1], [2], [1,2] ]</td></tr><tr><td>3</td><td>[ [1], [2], [3], [1,2], [1,3], [2,3], [1,2,3] ]</td></tr><tr><td>4</td><td>거의 모든 가능한 증가 부분 수열이 등장함 (약 15개)</td></tr></tbody></table></figure>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--50);margin-bottom:var(--wp--preset--spacing--50)"/>



<h3 class="wp-block-heading">2차 시도 &#8211; <strong>이분 탐색 + 인덱스 추적</strong>을 이용한 LIS 복원 / O(N log N)</h3>



<figure class="wp-block-image size-full"><img decoding="async" width="1042" height="39" src="https://lycos7560.com/wp-content/uploads/2025/10/image-7.png" alt="" class="wp-image-40322" srcset="https://lycos7560.com/wp-content/uploads/2025/10/image-7.png 1042w, https://lycos7560.com/wp-content/uploads/2025/10/image-7-300x11.png 300w, https://lycos7560.com/wp-content/uploads/2025/10/image-7-768x29.png 768w" sizes="(max-width: 1042px) 100vw, 1042px" /></figure>



<p class="wp-block-paragraph">최장 증가 수열 (LIS, Longest Increasing Subsequence)</p>



<pre class="EnlighterJSRAW" data-enlighter-language="cpp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#include &lt;iostream>
#include &lt;vector>
#include &lt;algorithm>

using namespace std;

// (LIS, Longest Increasing Subsequence)

int main()
{
    ios::sync_with_stdio(false);
    std::cin.tie(NULL);
    std::cout.tie(NULL);

    int N;
    std::cin >> N;

    vector&lt;int> input(N);
    for (int i = 0; i &lt; N; i++)
        std::cin >> input[i];

    vector&lt;int> tail;  // LIS를 구성하는 인덱스들
    vector&lt;int> prev_idx(N, -1);  //각 요소가 LIS에 포함될 때, 그 직전 요소의 인덱스를 저장


    for (int i = 0; i &lt; N; i++)
    {
        // 이분 탐색으로 input[i]가 tail 배열에서 들어가야 할 위치 찾기
        int lo = 0;
        int hi = (int)tail.size() - 1;
        int pos = (int)tail.size(); // 기본값은 맨 뒤

        while (lo &lt;= hi)
        {
            int mid = (lo + hi) / 2;
            // input[i]보다 크거나 같은 첫 번째 tail 원소 위치(pos)를 찾
            if (input[tail[mid]] &lt; input[i])
            {
                lo = mid + 1;
            }
            else
            {
                pos = mid;
                hi = mid - 1;
            }
        }

        // 이전 인덱스 설정
        if (pos > 0)
        {
            prev_idx[i] = tail[pos - 1];
        }
        else
        {
            prev_idx[i] = -1;  // 첫 번째 요소
        }

        // tail 업데이트
        if (pos == (int)tail.size())
        {
            tail.push_back(i);
        }
        else
        {
            tail[pos] = i;
        }
    }

    // 결과: LIS 길이
    int lis_len = (int)tail.size();
    std::cout &lt;&lt; lis_len &lt;&lt; "\n";

    // 실제 LIS 수열 재구성
    vector&lt;int> lis;
    for (int idx = tail.back(); idx != -1; idx = prev_idx[idx])
    {
        lis.push_back(input[idx]);
    }
    reverse(lis.begin(), lis.end());

    for (int v : lis)
        std::cout &lt;&lt; v &lt;&lt; " ";
    std::cout &lt;&lt; "\n";

    return 0;
}</pre>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="651" height="324" src="https://lycos7560.com/wp-content/uploads/2025/10/image-5.png" alt="" class="wp-image-40319" srcset="https://lycos7560.com/wp-content/uploads/2025/10/image-5.png 651w, https://lycos7560.com/wp-content/uploads/2025/10/image-5-300x149.png 300w" sizes="(max-width: 651px) 100vw, 651px" /></figure>



<p class="wp-block-paragraph"><code>input[i]</code>가 들어가야 할 위치(<code>pos</code>)를 찾음</p>



<p class="wp-block-paragraph">즉, <code>tail</code> 배열 내에서 <strong>input[i]보다 작지만 가장 큰 값 다음 위치</strong>를 찾는다.</p>



<figure class="wp-block-image size-full"><img decoding="async" width="513" height="466" src="https://lycos7560.com/wp-content/uploads/2025/10/image-6.png" alt="" class="wp-image-40320" srcset="https://lycos7560.com/wp-content/uploads/2025/10/image-6.png 513w, https://lycos7560.com/wp-content/uploads/2025/10/image-6-300x273.png 300w" sizes="(max-width: 513px) 100vw, 513px" /></figure>



<p class="wp-block-paragraph"><code>prev_idx[i]</code>는 <code>input[i]</code> 바로 앞에 올 LIS 원소의 인덱스입니다.</p>



<p class="wp-block-paragraph"><code>pos > 0</code>이면 → 현재 원소가 &#8220;길이 pos+1&#8243;짜리 LIS의 마지막이 되므로 &#8220;그 바로 이전 원소&#8221;는 <code>tail[pos - 1]</code></p>



<p class="wp-block-paragraph"><code>pos == 0</code>이면 → 수열의 첫 번째 원소이므로 이전이 없음</p>



<p class="wp-block-paragraph"><code>pos == tail.size()</code> → <code>input[i]</code>가 지금 까지의 모든 수보다 크므로 LIS 길이 1 증가</p>



<p class="wp-block-paragraph">그렇지 않으면 → 기존 LIS 후보 중 &#8220;끝값이 더 큰 것&#8221;을 <code>input[i]</code>로 <strong>치환</strong> (더 작은 끝값 유지)</p>



<h4 class="wp-block-heading">예시 1</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">input = [5, 2, 8, 6, 3, 6, 9, 7]</pre>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-table"><table><thead><tr><th class="has-text-align-left" data-align="left">단계</th><th class="has-text-align-left" data-align="left">i</th><th class="has-text-align-left" data-align="left">input[i]</th><th class="has-text-align-left" data-align="left">tail (인덱스)</th><th class="has-text-align-left" data-align="left">tail (값으로 표현)</th><th class="has-text-align-left" data-align="left">prev_idx</th><th class="has-text-align-left" data-align="left">설명</th></tr></thead><tbody><tr><td class="has-text-align-left" data-align="left">0</td><td class="has-text-align-left" data-align="left">0</td><td class="has-text-align-left" data-align="left">5</td><td class="has-text-align-left" data-align="left">[0]</td><td class="has-text-align-left" data-align="left">[5]</td><td class="has-text-align-left" data-align="left">[-1, ?, ?, ?, ?, ?, ?, ?]</td><td class="has-text-align-left" data-align="left">첫 번째 원소 → 새로운 LIS 시작</td></tr><tr><td class="has-text-align-left" data-align="left">1</td><td class="has-text-align-left" data-align="left">1</td><td class="has-text-align-left" data-align="left">2</td><td class="has-text-align-left" data-align="left">[1]</td><td class="has-text-align-left" data-align="left">[2]</td><td class="has-text-align-left" data-align="left">[-1, -1, ?, ?, ?, ?, ?, ?]</td><td class="has-text-align-left" data-align="left">2 &lt; 5 → 기존 tail[0] 교체 (더 작은 끝값 유지)</td></tr><tr><td class="has-text-align-left" data-align="left">2</td><td class="has-text-align-left" data-align="left">2</td><td class="has-text-align-left" data-align="left">8</td><td class="has-text-align-left" data-align="left">[1, 2]</td><td class="has-text-align-left" data-align="left">[2, 8]</td><td class="has-text-align-left" data-align="left">[-1, -1, 1, ?, ?, ?, ?, ?]</td><td class="has-text-align-left" data-align="left">8 &gt; 2 → 길이 2짜리 LIS 형성</td></tr><tr><td class="has-text-align-left" data-align="left">3</td><td class="has-text-align-left" data-align="left">3</td><td class="has-text-align-left" data-align="left">6</td><td class="has-text-align-left" data-align="left">[1, 3]</td><td class="has-text-align-left" data-align="left">[2, 6]</td><td class="has-text-align-left" data-align="left">[-1, -1, 1, 1, ?, ?, ?, ?]</td><td class="has-text-align-left" data-align="left">6은 2보다 크지만 8보다 작음 → 8을 6으로 교체</td></tr><tr><td class="has-text-align-left" data-align="left">4</td><td class="has-text-align-left" data-align="left">4</td><td class="has-text-align-left" data-align="left">3</td><td class="has-text-align-left" data-align="left">[1, 4]</td><td class="has-text-align-left" data-align="left">[2, 3]</td><td class="has-text-align-left" data-align="left">[-1, -1, 1, 1, 1, ?, ?, ?]</td><td class="has-text-align-left" data-align="left">3은 2보다 크고 6보다 작음 → 6을 3으로 교체</td></tr><tr><td class="has-text-align-left" data-align="left">5</td><td class="has-text-align-left" data-align="left">5</td><td class="has-text-align-left" data-align="left">6</td><td class="has-text-align-left" data-align="left">[1, 4, 5]</td><td class="has-text-align-left" data-align="left">[2, 3, 6]</td><td class="has-text-align-left" data-align="left">[-1, -1, 1, 1, 1, 4, ?, ?]</td><td class="has-text-align-left" data-align="left">6은 3보다 크므로 길이 3짜리 LIS 생성</td></tr><tr><td class="has-text-align-left" data-align="left">6</td><td class="has-text-align-left" data-align="left">6</td><td class="has-text-align-left" data-align="left">9</td><td class="has-text-align-left" data-align="left">[1, 4, 5, 6]</td><td class="has-text-align-left" data-align="left">[2, 3, 6, 9]</td><td class="has-text-align-left" data-align="left">[-1, -1, 1, 1, 1, 4, 5, ?]</td><td class="has-text-align-left" data-align="left">9 &gt; 6 → 길이 4짜리 LIS 생성</td></tr><tr><td class="has-text-align-left" data-align="left">7</td><td class="has-text-align-left" data-align="left">7</td><td class="has-text-align-left" data-align="left">7</td><td class="has-text-align-left" data-align="left">[1, 4, 5, 7]</td><td class="has-text-align-left" data-align="left">[2, 3, 6, 7]</td><td class="has-text-align-left" data-align="left">[-1, -1, 1, 1, 1, 4, 5, 5]</td><td class="has-text-align-left" data-align="left">7은 6보다 크지만 9보다 작음 → 9를 7로 교체</td></tr></tbody></table></figure>



<div style="height:15px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">예시 2</h4>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">이분 탐색을 이용한 LIS 구성 로직

input = [3, 5, 2, 7, 4, 1, 8]

--------------------------------

i=0 (값: 3)
tail: [] (빈 배열)
이분탐색: tail.size() = 0 → while문 스킵
pos = 0 (기본값)

prev_idx[0] = -1 (pos=0이므로)
tail 업데이트: pos == tail.size() → push_back(0)
결과: tail = [0] (값: [3])

--------------------------------

i=1 (값: 5)
tail: [0] (값: [3])
이분탐색:
  lo=0, hi=0, mid=0
  input[tail[0]] = 3 &lt; 5 → lo = mid+1 = 1
  lo=1 > hi=0 → 종료
pos = tail.size() = 1

prev_idx[1] = tail[0] = 0 (5 앞에 3)
tail 업데이트: push_back(1)
결과: tail = [0,1] (값: [3,5])

--------------------------------

i=2 (값: 2)
tail: [0,1] (값: [3,5])
이분탐색:
  lo=0, hi=1, mid=0
  input[tail[0]] = 3 >= 2 → pos=0, hi=-1
  lo=0 > hi=-1 → 종료
pos = 0

prev_idx[2] = -1 (pos=0이므로)
tail 업데이트: tail[0] = 2
결과: tail = [2,1] (값: [2,5])

--------------------------------

i=3 (값: 7)
tail: [2,1] (값: [2,5])
이분탐색:
  lo=0, hi=1, mid=0: input[tail[0]]=2 &lt; 7 → lo=1
  lo=1, hi=1, mid=1: input[tail[1]]=5 &lt; 7 → lo=2
  lo=2 > hi=1 → 종료
pos = tail.size() = 2

prev_idx[3] = tail[1] = 1 (7 앞에 5)
tail 업데이트: push_back(3)
결과: tail = [2,1,3] (값: [2,5,7])

--------------------------------

i=4 (값: 4)
tail: [2,1,3] (값: [2,5,7])
이분탐색:
  lo=0, hi=2, mid=1: input[tail[1]]=5 >= 4 → pos=1, hi=0
  lo=0, hi=0, mid=0: input[tail[0]]=2 &lt; 4 → lo=1
  lo=1 > hi=0 → 종료
pos = 1

prev_idx[4] = tail[0] = 2 (4 앞에 2)
tail 업데이트: tail[1] = 4
결과: tail = [2,4,3] (값: [2,4,7])

--------------------------------

i=5 (값: 1)
tail: [2,4,3] (값: [2,4,7])
이분탐색:
  lo=0, hi=2, mid=1: input[tail[1]]=4 >= 1 → pos=1, hi=0
  lo=0, hi=0, mid=0: input[tail[0]]=2 >= 1 → pos=0, hi=-1
  lo=0 > hi=-1 → 종료
pos = 0

prev_idx[5] = -1
tail 업데이트: tail[0] = 5
결과: tail = [5,4,3] (값: [1,4,7])

--------------------------------

i=6 (값: 8)

tail: [5,4,3] (값: [1,4,7])
이분탐색:
  lo=0, hi=2, mid=1: input[tail[1]]=4 &lt; 8 → lo=2
  lo=2, hi=2, mid=2: input[tail[2]]=7 &lt; 8 → lo=3
  lo=3 > hi=2 → 종료
pos = tail.size() = 3

prev_idx[6] = tail[2] = 3 (8 앞에 7)
tail 업데이트: push_back(6)
결과: tail = [5,4,3,6] (값: [1,4,7,8])

</pre>



<p class="wp-block-paragraph"></p>
<p>The post <a href="https://lycos7560.com/cpp/%eb%b0%b1%ec%a4%80-14003%eb%b2%88-%ea%b0%80%ec%9e%a5-%ea%b8%b4-%ec%a6%9d%ea%b0%80%ed%95%98%eb%8a%94-%eb%b6%80%eb%b6%84-%ec%88%98%ec%97%b4-5-c/40314/">백준 14003번 (가장 긴 증가하는 부분 수열 5, C++)</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/cpp/%eb%b0%b1%ec%a4%80-14003%eb%b2%88-%ea%b0%80%ec%9e%a5-%ea%b8%b4-%ec%a6%9d%ea%b0%80%ed%95%98%eb%8a%94-%eb%b6%80%eb%b6%84-%ec%88%98%ec%97%b4-5-c/40314/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>백준 1655번 (가운데를 말해요, C++)</title>
		<link>https://lycos7560.com/cpp/%eb%b0%b1%ec%a4%80-1655%eb%b2%88-%ea%b0%80%ec%9a%b4%eb%8d%b0%eb%a5%bc-%eb%a7%90%ed%95%b4%ec%9a%94-c/40309/</link>
					<comments>https://lycos7560.com/cpp/%eb%b0%b1%ec%a4%80-1655%eb%b2%88-%ea%b0%80%ec%9a%b4%eb%8d%b0%eb%a5%bc-%eb%a7%90%ed%95%b4%ec%9a%94-c/40309/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Mon, 13 Oct 2025 02:09:45 +0000</pubDate>
				<category><![CDATA[BaekjoonOnlineJudge]]></category>
		<category><![CDATA[C++/CPP]]></category>
		<category><![CDATA[1655]]></category>
		<category><![CDATA[1655번]]></category>
		<category><![CDATA[Baekjoon]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[C++ 구현]]></category>
		<category><![CDATA[cpp]]></category>
		<category><![CDATA[O(log n)]]></category>
		<category><![CDATA[push-pop 연산]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[Two Heaps]]></category>
		<category><![CDATA[가운데를 말해요]]></category>
		<category><![CDATA[개발 능력]]></category>
		<category><![CDATA[게임 구현]]></category>
		<category><![CDATA[경계 조건]]></category>
		<category><![CDATA[계산적 사고]]></category>
		<category><![CDATA[고급 기법]]></category>
		<category><![CDATA[공간 복잡도]]></category>
		<category><![CDATA[공간 효율성]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[교육적 예제]]></category>
		<category><![CDATA[구현 기술]]></category>
		<category><![CDATA[균형 유지]]></category>
		<category><![CDATA[기본 개념]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[논리적 사고]]></category>
		<category><![CDATA[다이어그램]]></category>
		<category><![CDATA[단계별 설명]]></category>
		<category><![CDATA[단계별 진행]]></category>
		<category><![CDATA[대량 데이터]]></category>
		<category><![CDATA[대안 접근법]]></category>
		<category><![CDATA[데이터 구조]]></category>
		<category><![CDATA[데이터 스트림]]></category>
		<category><![CDATA[동생 게임]]></category>
		<category><![CDATA[동작 원리]]></category>
		<category><![CDATA[동적 데이터]]></category>
		<category><![CDATA[동적 중간값]]></category>
		<category><![CDATA[디자인 패턴]]></category>
		<category><![CDATA[로그 시간]]></category>
		<category><![CDATA[메모리 사용]]></category>
		<category><![CDATA[문제 분석]]></category>
		<category><![CDATA[문제 해결]]></category>
		<category><![CDATA[문제 해결력]]></category>
		<category><![CDATA[백준]]></category>
		<category><![CDATA[백준 1655]]></category>
		<category><![CDATA[백준 1655번]]></category>
		<category><![CDATA[백준이]]></category>
		<category><![CDATA[범위 제한]]></category>
		<category><![CDATA[복잡도 분석]]></category>
		<category><![CDATA[상세 설명]]></category>
		<category><![CDATA[상태 변화]]></category>
		<category><![CDATA[성능 개선]]></category>
		<category><![CDATA[성능 튜닝]]></category>
		<category><![CDATA[성능 평가]]></category>
		<category><![CDATA[소프트웨어 공학]]></category>
		<category><![CDATA[속도 개선]]></category>
		<category><![CDATA[수열 처리]]></category>
		<category><![CDATA[숫자 스트림]]></category>
		<category><![CDATA[스트리밍 알고리즘]]></category>
		<category><![CDATA[시각화]]></category>
		<category><![CDATA[시간 복잡도]]></category>
		<category><![CDATA[시간 효율성]]></category>
		<category><![CDATA[실시간 응용]]></category>
		<category><![CDATA[실시간 중간값]]></category>
		<category><![CDATA[실시간 처리]]></category>
		<category><![CDATA[실용적 구현]]></category>
		<category><![CDATA[실제 구현]]></category>
		<category><![CDATA[심화 학습]]></category>
		<category><![CDATA[알고리즘]]></category>
		<category><![CDATA[알고리즘 문제]]></category>
		<category><![CDATA[알고리즘 비교]]></category>
		<category><![CDATA[알고리즘 최적화]]></category>
		<category><![CDATA[알고리즘 패턴]]></category>
		<category><![CDATA[알고리즘 학습]]></category>
		<category><![CDATA[연속된 데이터]]></category>
		<category><![CDATA[연습 문제]]></category>
		<category><![CDATA[예외 상황]]></category>
		<category><![CDATA[예제 시뮬레이션]]></category>
		<category><![CDATA[온라인 알고리즘]]></category>
		<category><![CDATA[우선순위 큐]]></category>
		<category><![CDATA[우선순위 큐 활용]]></category>
		<category><![CDATA[음수 처리]]></category>
		<category><![CDATA[응용 기술]]></category>
		<category><![CDATA[이해하기 쉬운]]></category>
		<category><![CDATA[입력 처리]]></category>
		<category><![CDATA[자료구조 공부]]></category>
		<category><![CDATA[자료구조 선택]]></category>
		<category><![CDATA[자료구조 설계]]></category>
		<category><![CDATA[작은 값 선택]]></category>
		<category><![CDATA[접근 방법]]></category>
		<category><![CDATA[조건 처리]]></category>
		<category><![CDATA[주요 개념]]></category>
		<category><![CDATA[중간 위치]]></category>
		<category><![CDATA[중간값 계산]]></category>
		<category><![CDATA[중간값 유지]]></category>
		<category><![CDATA[중간값 찾기]]></category>
		<category><![CDATA[중앙값]]></category>
		<category><![CDATA[짝수 경우]]></category>
		<category><![CDATA[최대 힙]]></category>
		<category><![CDATA[최소 힙]]></category>
		<category><![CDATA[최적 해법]]></category>
		<category><![CDATA[최적화 기법]]></category>
		<category><![CDATA[출력 생성]]></category>
		<category><![CDATA[컴퓨터 과학]]></category>
		<category><![CDATA[코드 분석]]></category>
		<category><![CDATA[코드 예시]]></category>
		<category><![CDATA[코딩 기법]]></category>
		<category><![CDATA[코딩 테스트]]></category>
		<category><![CDATA[코딩테스트]]></category>
		<category><![CDATA[코테]]></category>
		<category><![CDATA[프로그래밍 스킬]]></category>
		<category><![CDATA[프로그래밍 연습]]></category>
		<category><![CDATA[프로그래밍 팁]]></category>
		<category><![CDATA[학습 포인트]]></category>
		<category><![CDATA[해결 전략]]></category>
		<category><![CDATA[핵심 아이디어]]></category>
		<category><![CDATA[효율성]]></category>
		<category><![CDATA[효율적 알고리즘]]></category>
		<category><![CDATA[효율적 처리]]></category>
		<category><![CDATA[효율적 코딩]]></category>
		<category><![CDATA[흐름도]]></category>
		<category><![CDATA[힙 균형]]></category>
		<category><![CDATA[힙 자료구조]]></category>
		<category><![CDATA[힙 크기 조정]]></category>
		<category><![CDATA[힙 활용]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=40309</guid>

					<description><![CDATA[<p>가운데를 말해요 https://www.acmicpc.net/problem/1655 시간 제한 메모리 제한 제출 정답 맞힌 사람 정답 비율 0.1 초 128 MB 80245 24515 18393 31.195% 문제 백준이는 동생에게 &#8220;가운데를 말해요&#8221; 게임을 가르쳐주고 있다. 백준이가&#160;정수를 하나씩 외칠때마다 동생은 지금까지 백준이가 말한 수 중에서 중간값을 말해야 한다. 만약, 그동안 백준이가 외친 수의 개수가 짝수개라면 중간에 있는 두 수 중에서 작은 수를 [&#8230;]</p>
<p>The post <a href="https://lycos7560.com/cpp/%eb%b0%b1%ec%a4%80-1655%eb%b2%88-%ea%b0%80%ec%9a%b4%eb%8d%b0%eb%a5%bc-%eb%a7%90%ed%95%b4%ec%9a%94-c/40309/">백준 1655번 (가운데를 말해요, C++)</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-87ca5ab3      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#가운데를-말해요" class="uagb-toc-link__trigger">가운데를 말해요</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#문제" class="uagb-toc-link__trigger">문제</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#입력" class="uagb-toc-link__trigger">입력</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#출력" class="uagb-toc-link__trigger">출력</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#예제-입력-1" class="uagb-toc-link__trigger">예제 입력 1</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#예제-출력-1" class="uagb-toc-link__trigger">예제 출력 1</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#출처" class="uagb-toc-link__trigger">출처</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#알고리즘-분류" class="uagb-toc-link__trigger">알고리즘 분류</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#1차-시도-배열-인덱스-실패-시간-초과" class="uagb-toc-link__trigger">1차 시도 &#8211; 배열 인덱스 (실패 / 시간 초과)</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#2차-시도-two-heaps-방식-성공" class="uagb-toc-link__trigger">2차 시도 &#8211; Two Heaps 방식 (성공)</a></ul></ol>					</div>
									</div>
				</div>
			


<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">가운데를 말해요 <img decoding="async" width="35" height="45" class="wp-image-37903" style="width: 35px;" src="https://lycos7560.com/wp-content/uploads/2024/03/Gold_2.jpg" alt="" srcset="https://lycos7560.com/wp-content/uploads/2024/03/Gold_2.jpg 400w, https://lycos7560.com/wp-content/uploads/2024/03/Gold_2-234x300.jpg 234w" sizes="(max-width: 35px) 100vw, 35px" /></h2>



<p class="wp-block-paragraph"><a href="https://www.acmicpc.net/problem/1655" target="_blank" rel="noreferrer noopener">https://www.acmicpc.net/problem/1655</a></p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>시간 제한</th><th>메모리 제한</th><th>제출</th><th>정답</th><th>맞힌 사람</th><th>정답 비율</th></tr></thead><tbody><tr><td>0.1 초</td><td>128 MB</td><td>80245</td><td>24515</td><td>18393</td><td>31.195%</td></tr></tbody></table></figure>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">문제</h3>



<p class="wp-block-paragraph">백준이는 동생에게 &#8220;가운데를 말해요&#8221; 게임을 가르쳐주고 있다. </p>



<p class="wp-block-paragraph">백준이가&nbsp;정수를 하나씩 외칠때마다 동생은 지금까지 백준이가 말한 수 중에서 중간값을 말해야 한다. </p>



<p class="wp-block-paragraph">만약, 그동안 백준이가 외친 수의 개수가 짝수개라면 중간에 있는 두 수 중에서 작은 수를 말해야 한다.</p>



<p class="wp-block-paragraph">예를 들어 백준이가 동생에게 1, 5, 2, 10, -99, 7, 5를 순서대로 외쳤다고 하면, 동생은 1, 1, 2, 2, 2, 2, 5를 차례대로 말해야 한다. </p>



<p class="wp-block-paragraph">백준이가 외치는 수가 주어졌을 때, 동생이 말해야 하는 수를 구하는 프로그램을 작성하시오.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">입력</h3>



<p class="wp-block-paragraph">첫째 줄에는 백준이가 외치는 정수의 개수 N이 주어진다. </p>



<p class="wp-block-paragraph">N은 1보다 크거나 같고, 100,000보다 작거나 같은 자연수이다. </p>



<p class="wp-block-paragraph">그 다음 N줄에 걸쳐서 백준이가 외치는 정수가 차례대로 주어진다. </p>



<p class="wp-block-paragraph">정수는 -10,000보다 크거나 같고, 10,000보다 작거나 같다.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">출력</h3>



<p class="wp-block-paragraph">한 줄에 하나씩 N줄에 걸쳐 백준이의 동생이 말해야 하는 수를 순서대로 출력한다.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">예제 입력 1</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">7
1
5
2
10
-99
7
5</pre>



<div style="height:31px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">예제 출력 1</h3>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">1
1
2
2
2
2
5</pre>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">출처</h3>



<ul class="wp-block-list">
<li>문제를 만든 사람:&nbsp;<a href="https://www.acmicpc.net/user/ntopia" target="_blank" rel="noreferrer noopener">ntopia</a></li>



<li>데이터를 추가한 사람:&nbsp;<a href="https://www.acmicpc.net/user/pichulia" target="_blank" rel="noreferrer noopener">pichulia</a></li>



<li>문제를 각색한 사람:&nbsp;<a href="https://www.acmicpc.net/user/baekjoon" target="_blank" rel="noreferrer noopener">baekjoon</a></li>
</ul>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">알고리즘 분류</h3>



<ul class="wp-block-list">
<li><a href="https://www.acmicpc.net/problem/tag/175" target="_blank" rel="noreferrer noopener">자료 구조</a></li>



<li><a href="https://www.acmicpc.net/problem/tag/59" target="_blank" rel="noreferrer noopener">우선순위 큐</a></li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--70);margin-bottom:var(--wp--preset--spacing--70)"/>



<h3 class="wp-block-heading">1차 시도 &#8211; 배열 인덱스 (실패 / 시간 초과)</h3>



<figure class="wp-block-image size-full"><img decoding="async" width="1041" height="34" src="https://lycos7560.com/wp-content/uploads/2025/10/image-1.png" alt="" class="wp-image-40311" srcset="https://lycos7560.com/wp-content/uploads/2025/10/image-1.png 1041w, https://lycos7560.com/wp-content/uploads/2025/10/image-1-300x10.png 300w, https://lycos7560.com/wp-content/uploads/2025/10/image-1-768x25.png 768w" sizes="(max-width: 1041px) 100vw, 1041px" /></figure>



<p class="wp-block-paragraph">배열을 기반으로, 중간값의 인덱스(<code>currentMedian</code>)를 유지하면서 새로운 값이 들어올 때마다 <code>leftCount</code>, <code>rightCount</code>를 조정하는 방식</p>



<pre class="EnlighterJSRAW" data-enlighter-language="cpp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#include &lt;iostream>
using namespace std;

int n = 0;
int num[20001] = { 0 };  // 값의 출현 횟수 (index = value + 10000)
int currentMedian = 0;   // 현재 중간값의 인덱스
int leftCount = 0;       // 중간값보다 작은 값들의 개수
int rightCount = 0;      // 중간값보다 큰 값들의 개수

// 실제 값 => 배열 인덱스로 변환
inline int GetIndex(int value) 
{
    return value + 10000;
}

// 배열 인덱스 => 실제 값으로 변환
inline int GetValue(int index) 
{
    return index - 10000;
}

int FindMedianOptimized(int newValue, int total)
{
    int newIdx = GetIndex(newValue);
    num[newIdx]++;

    // 새 값의 위치에 따라 좌우 카운트 조정
    if (newIdx &lt; currentMedian) leftCount++;
    else if (newIdx > currentMedian) rightCount++;
    else rightCount++; // 같은 값일 경우 간단히 오른쪽으로 분류

    // 목표 중간 위치 계산
    int targetPos = (total + 1) / 2;

    // 중간값 인덱스를 왼쪽으로 이동 (왼쪽 원소가 너무 많을 때)
    while (leftCount >= targetPos) {
        currentMedian--;
        leftCount -= num[currentMedian];
        rightCount += num[currentMedian];
    }

    // 중간값 인덱스를 오른쪽으로 이동 (왼쪽 원소가 부족할 때)
    while (leftCount + num[currentMedian] &lt; targetPos) {
        leftCount += num[currentMedian];
        currentMedian++;
        rightCount -= num[currentMedian];
    }

    // 현재 중간값 반환
    return GetValue(currentMedian);
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    cin >> n;
    int value = 0;

    // 첫 번째 입력값으로 초기화
    cin >> value;
    num[GetIndex(value)]++;
    currentMedian = GetIndex(value);
    leftCount = 0;
    rightCount = 0;

    // 첫 번째 값 => 중간값
    cout &lt;&lt; value &lt;&lt; "\n"; 

    for (int i = 2; i &lt;= n; ++i) 
    {
        cin >> value;
        cout &lt;&lt; FindMedianOptimized(value, i) &lt;&lt; "\n";
    }

    return 0;
}
</pre>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<h4 class="wp-block-heading">시간 초과의 원인</h4>



<figure class="wp-block-image size-full"><img decoding="async" width="610" height="311" src="https://lycos7560.com/wp-content/uploads/2025/10/image-2.png" alt="" class="wp-image-40312" srcset="https://lycos7560.com/wp-content/uploads/2025/10/image-2.png 610w, https://lycos7560.com/wp-content/uploads/2025/10/image-2-300x153.png 300w" sizes="(max-width: 610px) 100vw, 610px" /></figure>



<p class="wp-block-paragraph">새로운 값이 입력될 때마다 <strong><code>currentMedian</code>을 1씩 이동</strong>하며 왼쪽/오른쪽 카운트를 갱신</p>



<p class="wp-block-paragraph"><code>currentMedian</code>의 이동 거리는 <strong>입력된 값의 분포에 따라서</strong> 문제가 생길 수 있음.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">// 최악의 경우
-10000, -9999, -9998, ... , 9999, 10000
</pre>



<div style="height:5px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph">매번 새로운 값이 들어올 때마다 <code>currentMedian</code>이 <strong>오른쪽 끝으로 한 칸씩 이동</strong></p>



<p class="wp-block-paragraph">매번 <code>while</code> 루프가 <strong>최대 20,000번 반복</strong>되는 불상사가 생길 수 있음</p>



<p class="wp-block-paragraph">입력 n = 100,000일 때 <strong>최악의 복잡도: <code>O(n * 20000)</code> = 2,000,000,000 (20억)</strong> </p>



<p class="wp-block-paragraph"><code>currentMedian</code> 부분을 개선 또는 다른 알고리즘을 사용하는 방법이 더 좋아보임</p>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--70);margin-bottom:var(--wp--preset--spacing--70)"/>



<h3 class="wp-block-heading">2차 시도 &#8211; Two Heaps 방식 (성공)</h3>



<figure class="wp-block-image size-full"><img decoding="async" width="1044" height="42" src="https://lycos7560.com/wp-content/uploads/2025/10/image.png" alt="" class="wp-image-40310" srcset="https://lycos7560.com/wp-content/uploads/2025/10/image.png 1044w, https://lycos7560.com/wp-content/uploads/2025/10/image-300x12.png 300w, https://lycos7560.com/wp-content/uploads/2025/10/image-768x31.png 768w" sizes="(max-width: 1044px) 100vw, 1044px" /></figure>



<p class="wp-block-paragraph"><code>maxHeap</code>(왼쪽) + <code>minHeap</code>(오른쪽)으로 균형 유지</p>



<p class="wp-block-paragraph"><code>maxHeap</code>: 중간값 이하의 값들 저장 (왼쪽 절반)</p>



<p class="wp-block-paragraph"><code>minHeap</code>: 중간값 이상의 값들 저장 (오른쪽 절반)</p>



<p class="wp-block-paragraph">균형 조정 시 힙에서 한 번씩 <code>push/pop</code> → <code>O(log n)</code></p>



<pre class="EnlighterJSRAW" data-enlighter-language="cpp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#include &lt;iostream>
#include &lt;queue>
using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int n;
    cin >> n;

    priority_queue&lt;int> maxHeap;                            // 왼쪽 절반 (최대 힙)
    priority_queue&lt;int, vector&lt;int>, greater&lt;int>> minHeap;  // 오른쪽 절반 (최소 힙)

    for (int i = 0; i &lt; n; ++i) 
    {
        int value;
        cin >> value;

        // 값 삽입: 왼쪽/오른쪽 균형 유지
        if (maxHeap.empty() || value &lt;= maxHeap.top())
            maxHeap.push(value);
        else
            minHeap.push(value);

        // 두 힙의 크기 균형 조정 (왼쪽 = 오른쪽 또는 +1)
        if (maxHeap.size() > minHeap.size() + 1) {
            minHeap.push(maxHeap.top());
            maxHeap.pop();
        }
        else if (minHeap.size() > maxHeap.size()) {
            maxHeap.push(minHeap.top());
            minHeap.pop();
        }

        // 현재 중간값 출력
        cout &lt;&lt; maxHeap.top() &lt;&lt; "\n";
    }

    return 0;
}
</pre>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">입력: [1, 5, 2, 10, -5, 8, 3]

단계별 힙 상태:

1. value=1
   maxHeap: [1]      minHeap: []
   중간값: 1

2. value=5
   maxHeap: [1]      minHeap: [5]
   중간값: 1

3. value=2
   maxHeap: [2, 1]   minHeap: [5]
   중간값: 2

4. value=10
   maxHeap: [2, 1]   minHeap: [5, 10]
   중간값: 2

5. value=-5
   maxHeap: [2, 1, -5] minHeap: [5, 10]
   중간값: 2

6. value=8
   maxHeap: [2, 1, -5] minHeap: [5, 8, 10]
   중간값: 2

7. value=3
   maxHeap: [3, 2, -5, 1] minHeap: [5, 8, 10]
   중간값: 3</pre>
<p>The post <a href="https://lycos7560.com/cpp/%eb%b0%b1%ec%a4%80-1655%eb%b2%88-%ea%b0%80%ec%9a%b4%eb%8d%b0%eb%a5%bc-%eb%a7%90%ed%95%b4%ec%9a%94-c/40309/">백준 1655번 (가운데를 말해요, C++)</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/cpp/%eb%b0%b1%ec%a4%80-1655%eb%b2%88-%ea%b0%80%ec%9a%b4%eb%8d%b0%eb%a5%bc-%eb%a7%90%ed%95%b4%ec%9a%94-c/40309/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>알고리즘 – 트라이(Trie) 자료구조</title>
		<link>https://lycos7560.com/etc/%ec%95%8c%ea%b3%a0%eb%a6%ac%ec%a6%98-%ed%8a%b8%eb%9d%bc%ec%9d%b4trie-%ec%9e%90%eb%a3%8c%ea%b5%ac%ec%a1%b0/33961/</link>
					<comments>https://lycos7560.com/etc/%ec%95%8c%ea%b3%a0%eb%a6%ac%ec%a6%98-%ed%8a%b8%eb%9d%bc%ec%9d%b4trie-%ec%9e%90%eb%a3%8c%ea%b5%ac%ec%a1%b0/33961/#respond</comments>
		
		<dc:creator><![CDATA[lycos7560]]></dc:creator>
		<pubDate>Tue, 14 Mar 2023 02:37:19 +0000</pubDate>
				<category><![CDATA[기타]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[cpp]]></category>
		<category><![CDATA[leaf node]]></category>
		<category><![CDATA[retrieval]]></category>
		<category><![CDATA[root node]]></category>
		<category><![CDATA[study]]></category>
		<category><![CDATA[Time Complexity]]></category>
		<category><![CDATA[tree]]></category>
		<category><![CDATA[Trie]]></category>
		<category><![CDATA[공부]]></category>
		<category><![CDATA[구조]]></category>
		<category><![CDATA[기본]]></category>
		<category><![CDATA[기초]]></category>
		<category><![CDATA[데이터]]></category>
		<category><![CDATA[시간 복잡도]]></category>
		<category><![CDATA[알고리즘]]></category>
		<category><![CDATA[자료]]></category>
		<category><![CDATA[자료 구조]]></category>
		<category><![CDATA[자료구조]]></category>
		<category><![CDATA[코딩테스트]]></category>
		<category><![CDATA[코테]]></category>
		<category><![CDATA[트라이]]></category>
		<category><![CDATA[트라이(Trie)]]></category>
		<guid isPermaLink="false">https://lycos7560.com/?p=33961</guid>

					<description><![CDATA[<p>트라이(Trie) 자료구조에 대한 글입니다.<br />
트라이(Trie)의 자료구조의 장점 및 단점, c++ 구현에 대하여 설명합니다. (This is an article about the Trie data structure.<br />
Explain the advantages and disadvantages of the data structure of Trie and the implementation of c++.)</p>
<p>The post <a href="https://lycos7560.com/etc/%ec%95%8c%ea%b3%a0%eb%a6%ac%ec%a6%98-%ed%8a%b8%eb%9d%bc%ec%9d%b4trie-%ec%9e%90%eb%a3%8c%ea%b5%ac%ec%a1%b0/33961/">알고리즘 – 트라이(Trie) 자료구조</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<script async="" src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5698326622209671" crossorigin="anonymous"></script>
<!-- HorizontalAD -->
<ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-5698326622209671" data-ad-slot="6908948342" data-ad-format="auto" data-full-width-responsive="true"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>


				<div class="wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-df0292cc      "
					data-scroll= "1"
					data-offset= "30"
					style=""
				>
				<div class="uagb-toc__wrap">
						<div class="uagb-toc__title">
							목차 테이블						</div>
																						<div class="uagb-toc__list-wrap ">
						<ol class="uagb-toc__list"><li class="uagb-toc__list"><a href="#트라이trie" class="uagb-toc-link__trigger">트라이(Trie)?</a><ul class="uagb-toc__list"><li class="uagb-toc__list"><a href="#트라이trie의-이점" class="uagb-toc-link__trigger">트라이(Trie)의 이점</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#트라이trie의-잠재적인-단점" class="uagb-toc-link__trigger">트라이(Trie)의 잠재적인 단점</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#트라이trie의-시간-복잡도" class="uagb-toc-link__trigger">트라이(Trie)의 시간 복잡도</a><li class="uagb-toc__list"><li class="uagb-toc__list"><a href="#트라이trie-구현-c" class="uagb-toc-link__trigger">트라이(Trie) 구현 (C++)</a></ul></ol>					</div>
									</div>
				</div>
			


<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<h1 class="wp-block-heading">트라이(Trie)?</h1>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide"/>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-medium-font-size wp-block-paragraph">Trie data structure는 문자열을 효율적으로 저장하고 검색하는 데 사용되는 Tree와 유사한 데이터 구조입니다.</p>



<p class="has-medium-font-size wp-block-paragraph">&#8220;Trie&#8221;라는 이름은 &#8220;트리&#8221;와 비슷하게 발음되는 &#8220;retrieval,&#8221;이라는 단어에서 유래되었습니다.</p>



<p class="has-medium-font-size wp-block-paragraph">검색할 때 볼 수 있는&nbsp;<strong>자동완성 기능, 사전 검색 등 문자열을 탐색하는데 특화</strong>되어있는 자료구조입니다.</p>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="883" height="823" src="https://lycos7560.com/wp-content/uploads/2023/03/image-53.png" alt="" class="wp-image-33963" srcset="https://lycos7560.com/wp-content/uploads/2023/03/image-53.png 883w, https://lycos7560.com/wp-content/uploads/2023/03/image-53-300x280.png 300w, https://lycos7560.com/wp-content/uploads/2023/03/image-53-768x716.png 768w" sizes="(max-width: 883px) 100vw, 883px" /><figcaption class="wp-element-caption">https://ko.wikipedia.org/wiki/%ED%8A%B8%EB%9D%BC%EC%9D%B4_(%EC%BB%B4%ED%93%A8%ED%8C%85)</figcaption></figure>



<p class="has-medium-font-size wp-block-paragraph">&#8220;A&#8221;, &#8220;to&#8221;, &#8220;tea&#8221;, &#8220;ted&#8221;, &#8220;ten&#8221;, &#8220;i&#8221;, &#8220;in&#8221;, &#8220;inn&#8221;를 키로 둔 트라이. </p>



<p class="has-medium-font-size wp-block-paragraph">이 예제에는 모든 자식 노드가 알파벳 순으로 왼쪽에서 오른쪽으로 정렬되어 있지는 않다. (루트 노드와 &#8216;t&#8217; 노드)</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-medium-font-size wp-block-paragraph">Trie에서 각 node는 문자열의 단일 문자를 나타내고 node에서 나오는 가장자리는 문자열의 다음 문자를 나타냅니다. </p>



<p class="has-medium-font-size wp-block-paragraph">Trie의 각 문자열은 root node에서 leaf node까지의 경로로 표시됩니다. </p>



<p class="has-medium-font-size wp-block-paragraph">root node에는 연결된 문자가 없으며 각 leaf node는 데이터 세트의 전체 문자열을 나타냅니다.</p>



<div style="height:30px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-medium-font-size wp-block-paragraph">Trie는 특히 공통 접두사를 공유하는 문자열을 검색할 때 문자열을 효율적으로 저장하고 검색하는 데 자주 사용됩니다. </p>



<p class="has-medium-font-size wp-block-paragraph">예를 들어 Trie를 사용하여 단어 사전을 저장할 수 있습니다. </p>



<p class="has-medium-font-size wp-block-paragraph">여기서 Trie의 각 node는 단어의 접두사를 나타냅니다. </p>



<p class="has-medium-font-size wp-block-paragraph">Trie를 root node에서 leaf node로 이동하면  leaf node와 관련된 전체 단어를 빠르게 검색할 수 있습니다.</p>



<div style="height:150px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">트라이(Trie)의 이점</h2>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:0;margin-bottom:0"/>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">1. 효율적인 접두사 검색</h3>



<p class="has-medium-font-size wp-block-paragraph">Trie는 특히 접두사 검색 쿼리에 효율적입니다. </p>



<p class="has-medium-font-size wp-block-paragraph">root node에서 접두사를 나타내는 node로 Trie를 순회하면 해당 접두사로 시작하는 데이터 세트의 모든 문자열을 검색할 수 있습니다. </p>



<p class="has-medium-font-size wp-block-paragraph">이는 자동 완성, 맞춤법 검사기 및 검색 엔진과 같은 응용 프로그램에서 유용합니다.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">2. 공간 효율성</h3>



<p class="has-medium-font-size wp-block-paragraph">Trie는 해시 테이블과 같은 다른 데이터 구조에 비해 매우 공간 효율적일 수 있습니다. </p>



<p class="has-medium-font-size wp-block-paragraph">문자열에 공통 접두사의 중복 저장을 방지하여 특히 문자열 수가 많은 데이터 세트의 경우 공간을 크게 절약할 수 있습니다.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">3. 빠른 삽입 및 삭제</h3>



<p class="has-medium-font-size wp-block-paragraph">Trie는 문자열의 빠른 삽입 및 삭제를 지원하며 최악의 경우 O(m)의 시간 복잡도(m 문자열의 길이)입니다. </p>



<p class="has-medium-font-size wp-block-paragraph">따라서 데이터 세트가 동적이며 자주 업데이트해야 하는 애플리케이션에서 유용합니다.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">4. 예측 텍스트 입력</h3>



<p class="has-medium-font-size wp-block-paragraph">Trie는 자동 완성 시스템을 구현하는 데 사용할 수 있습니다. </p>



<p class="has-medium-font-size wp-block-paragraph">여기서 시스템은 사용자 입력을 기반으로 다음 단어나 구문을 제안합니다. </p>



<p class="has-medium-font-size wp-block-paragraph">자주 사용되는 단어와 구문의 Trie를 저장함으로써 </p>



<p class="has-medium-font-size wp-block-paragraph">시스템은 사용자의 현재 입력을 기반으로 가장 가능성이 높은 다음 단어를 제안할 수 있습니다.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">5. 낮은 메모리 오버헤드</h3>



<p class="has-medium-font-size wp-block-paragraph">Trie는 특히 ASCII 또는 유니코드와 같은 작은 문자 세트의 경우 메모리 오버헤드가 낮습니다. </p>



<p class="has-medium-font-size wp-block-paragraph">따라서 임베디드 시스템 및 기타 메모리 제약 환경에서 사용하기에 적합합니다.</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-medium-font-size wp-block-paragraph">전반적으로 Trie 데이터 구조는 문자열의 데이터 세트를 효율적으로 저장하고 처리하기 위한 강력한 도구입니다. </p>



<p class="has-medium-font-size wp-block-paragraph">특히 기본 사용 사례가 접두사를 검색하거나 시퀀스의 다음 단어를 예측하는 경우에 그렇습니다.</p>



<div style="height:150px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">트라이(Trie)의 잠재적인 단점</h2>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:0;margin-bottom:0"/>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">1. 메모리 요구 사항</h3>



<p class="has-medium-font-size wp-block-paragraph">Trie는 특히 문자열이 길거나 문자 집합이 큰 경우 </p>



<p class="has-medium-font-size wp-block-paragraph">큰 문자열 데이터 세트를 저장하기 위해 상당한 양의 메모리를 요구할 수 있습니다. </p>



<p class="has-medium-font-size wp-block-paragraph">이는 메모리 사용량이 중요한 환경이나 응용 프로그램에서의 사용을 제한할 수 있습니다.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">2. 접두사가 아닌 쿼리에 대한 느린 검색 시간</h3>



<p class="has-medium-font-size wp-block-paragraph">Trie는 접두사 검색 쿼리에 효율적이지만 접두사가 아닌 쿼리에 대한 다른 데이터 구조보다 느릴 수 있습니다. </p>



<p class="has-medium-font-size wp-block-paragraph">알고리즘이 쿼리와 일치하는 모든 문자열을 찾기 위해 각 노드의 전체 하위 트리를 탐색해야 하므로 </p>



<p class="has-medium-font-size wp-block-paragraph">해시 테이블과 같은 다른 데이터 구조에 비해 검색 시간이 느려질 수 있기 때문입니다.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">3. 복잡성</h3>



<p class="has-medium-font-size wp-block-paragraph">Trie 데이터 구조의 구현 및 유지 관리는 </p>



<p class="has-medium-font-size wp-block-paragraph">엄청나게 큰 데이터 세트의 경우 또는 문자 집합이 매우 복잡한 경우에</p>



<p class="has-medium-font-size wp-block-paragraph">다른 데이터 구조보다 더 복잡할 수 있습니다. </p>



<p class="has-medium-font-size wp-block-paragraph">이로 인해 개발 시간이 길어지고 개발 비용이 높아질 수 있습니다.</p>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<h3 class="wp-block-heading">4. 희소 데이터 집합에 대한 비효율적인 메모리 사용</h3>



<p class="has-medium-font-size wp-block-paragraph">데이터 집합에 희소 문자열이 많이 포함되어 있거나 공통 접두사가 거의 없는 경우 </p>



<p class="has-medium-font-size wp-block-paragraph">Trie는 가장 메모리 효율적인 데이터 구조가 아닐 수 있습니다. </p>



<p class="has-medium-font-size wp-block-paragraph">이는 Trie가 많은 빈 노드를 저장해야 하므로 메모리가 낭비될 수 있기 때문입니다.</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-medium-font-size wp-block-paragraph">전반적으로 Trie 데이터 구조는 효율적인 문자열 처리를 위한 강력한 도구이지만 </p>



<p class="has-medium-font-size wp-block-paragraph">응용 프로그램의 특정 요구 사항에 따라 항상 최선의 선택이 아닐 수도 있습니다.</p>



<div style="height:150px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">트라이(Trie)의 시간 복잡도</h2>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:0;margin-bottom:0"/>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<div style="height:50px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="has-medium-font-size wp-block-paragraph">일반적으로 Trie의 생성 시간 복잡도는 O(M x L), 탐색 시간 복잡도는 O(L)이다.</p>



<p class="has-medium-font-size wp-block-paragraph">제일 긴 문자열의 길이를 L이라 하고, 총 문자열들의 수를 M이라 할 때 시간 복잡도는 위와 같다.</p>



<p class="has-medium-font-size wp-block-paragraph">생성 시간 복잡도는 모든 문자열 M 개를 넣어야 하고, </p>



<p class="has-medium-font-size wp-block-paragraph">M 개에 대해서 트라이에 넣는 건 가장 긴 문자열 길이인 L 만큼 걸리므로 O(MxL)의 시간 복잡도를 가진다. (삽입은 O(L)이다.)</p>



<p class="has-medium-font-size wp-block-paragraph">탐색 시간 복잡도는 트리를 제일 깊게 탐색하는 경우는 가장 긴 문자열 길이인 L까지 깊게 들어가는 것이므로 O(L)의 시간 복잡도를 가진다.</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-default" style="margin-top:var(--wp--preset--spacing--80);margin-bottom:var(--wp--preset--spacing--80)"/>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">트라이(Trie) 구현 (C++)</h2>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<pre class="EnlighterJSRAW" data-enlighter-language="cpp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#include &lt;iostream>
#include &lt;unordered_map>

using namespace std;

// TrieNode클래스를 사용하여 Trie의 각 노드를 표현
class TrieNode {

public:
    unordered_map&lt;char, TrieNode*> children;
    bool isEndOfWord;

    TrieNode() { 
        isEndOfWord = false;
    }
    
};

// Trie 클래스
class Trie {

    // Trie의 루트 노드에 대한 포인터인 Trie개인 멤버 변수
    private: 
        TrieNode* root; // 루트 노드

// 생성자새 인스턴스를 만들고 Trie를 초기화합
    public:
        Trie() {
            root = new TrieNode();
        }


    // 문자열을 받아 Trie에 추가합니다. 
    // 루트 노드에서 시작하여 Trie 아래로 이동하여 단어의 각 문자에 필요한 새 노드를 만듭니다.
    void insert(string word) {
        TrieNode* curr = root; // 시작
        for (char c : word) {
            if (curr->children.find(c) == curr->children.end()) {
                // Trie에 없다면 새 노드 생성
                curr->children[c] = new TrieNode();
            }
            curr = curr->children[c]; // Trie에 이미 존재하는 경우 기존 노드로 이동
        }
        // 단어의 끝을 나타내는 isEndOfWord bool값
        curr->isEndOfWord = true;
    }

    // 단어를 검색합니다.
    bool search(string word) {
        TrieNode* curr = root;
        for (char c : word) {
            if (curr->children.find(c) == curr->children.end()) {
                return false;
            }
            curr = curr->children[c];
        }
        return curr->isEndOfWord;
    }

    // prefix(접두사)로 시작하는 단어가 Trie에 있는지 확인
    bool startsWith(string prefix) {
        TrieNode* curr = root;
        for (char c : prefix) {
            if (curr->children.find(c) == curr->children.end()) {
                return false;
            }
            curr = curr->children[c];
        }
        return true;
    }
};

int main() {

    Trie trie;
    trie.insert("hello");
    trie.insert("world");
    trie.insert("hello world");

    cout &lt;&lt; trie.search("hello") &lt;&lt; "\n";      // output: 1 (true)
    cout &lt;&lt; trie.search("hello world") &lt;&lt; "\n"; // output: 1 (true)
    cout &lt;&lt; trie.search("hi") &lt;&lt; "\n";         // output: 0 (false)

    cout &lt;&lt; trie.startsWith("hell") &lt;&lt; "\n";    // output: 1 (true)
    cout &lt;&lt; trie.startsWith("heaven") &lt;&lt; "\n";  // output: 0 (false)

    return 0;
}</pre>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--80);margin-bottom:var(--wp--preset--spacing--80)"/>



<figure class="wp-block-embed is-type-wp-embed is-provider-어제와-내일의-나-그-사이의-이야기 wp-block-embed-어제와-내일의-나-그-사이의-이야기"><div class="wp-block-embed__wrapper">
<blockquote class="wp-embedded-content" data-secret="UKL9lnwUUR"><a href="https://lycos7560.com/cpp/programmers/programmers-17685-3%ec%b0%a8-%ec%9e%90%eb%8f%99%ec%99%84%ec%84%b1-2018-kakao-blind-recruitment/33995/">Programmers 17685 [3차] 자동완성 [2018 KAKAO BLIND RECRUITMENT]</a></blockquote><iframe loading="lazy" class="wp-embedded-content" sandbox="allow-scripts" security="restricted"  title="&#8220;Programmers 17685 [3차] 자동완성 [2018 KAKAO BLIND RECRUITMENT]&#8221; &#8212; 어제와 내일의 나 그 사이의 이야기" src="https://lycos7560.com/cpp/programmers/programmers-17685-3%ec%b0%a8-%ec%9e%90%eb%8f%99%ec%99%84%ec%84%b1-2018-kakao-blind-recruitment/33995/embed/#?secret=0L39VdZa1Y#?secret=UKL9lnwUUR" data-secret="UKL9lnwUUR" width="600" height="338" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
</div></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="cpp" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">#include &lt;string>
#include &lt;vector>
#include &lt;unordered_map>

using namespace std;

// TrieNode클래스를 사용하여 Trie의 각 노드를 표현
class TrieNode {
public:
    unordered_map&lt;char, TrieNode*> children;
    int num; // 연관된 단어의 개수를 저장
    TrieNode() {
        num = 0;
    }
};

// Trie 클래스
class Trie {

private: // Trie의 루트 노드에 대한 포인터인 Trie개인 멤버 변수
    TrieNode* root; // 루트 노드


public:
    Trie() { // 생성자새 인스턴스를 만들고 Trie를 초기화
        root = new TrieNode();
    }

    // 문자열을 받아 Trie에 추가합니다. 
    // 루트 노드에서 시작하여 Trie 아래로 이동하여 단어의 각 문자에 필요한 새 노드를 만듭니다.
    void insert(string word) {
        TrieNode* curr = root; // 시작
        for (char c : word) {
            if (curr->children.find(c) == curr->children.end()) {
                // Trie에 없다면 새 노드 생성
                curr->children[c] = new TrieNode();
            }

            // Trie에 이미 존재하는 경우 기존 노드로 이동
            curr = curr->children[c];
            curr->num++; // 연관된 단어의 개수 추가
        }
    }

    // 단어를 검색합니다.
    // 연관된 단어의 개수가 1이라면 글자수 반환
    int search(string word) {
        TrieNode* curr = root;
        int cnt = 0;
        for (char c : word) {
            curr = curr->children[c];
            cnt++;
            if (curr->num == 1) {
                // 연관된 단어의 개수가 1이라면 
                // 자동완성
                return cnt;
            }
        }
        return 9999; // 문제에서 나올 수 없는 경우 
    }

    // prefix(접두사)로 시작하는 단어가 Trie에 있는지 확인
    int startsWith(string prefix) {
        TrieNode* curr = root;
        for (char c : prefix) {
            if (curr->children.find(c) == curr->children.end()) {
                return false;
            }
            curr = curr->children[c];
        }
        return curr->children.size();
    }

};

int solution(vector&lt;string> words) {
    int answer = 0;
    Trie trie;
    for (auto&amp; it : words) {
        trie.insert(it);
    }

    for (auto&amp; it : words) {
        if (trie.startsWith(it) >= 1) {
            // 접두사로 시작하는 단어가 있다면 
            // 단어 전체를 입력해야한다.
            answer += it.length();
            continue;
        }

        // 자동완성 확인
        answer += trie.search(it);
    }

    return answer;
}</pre>



<hr class="wp-block-separator has-alpha-channel-opacity is-style-wide" style="margin-top:var(--wp--preset--spacing--70);margin-bottom:var(--wp--preset--spacing--70)"/>



<div style="height:40px" aria-hidden="true" class="wp-block-spacer"></div>



<p class="wp-block-paragraph"><a href="https://www.acmicpc.net/problemset?sort=ac_desc&amp;algo=79">https://www.acmicpc.net/problemset?sort=ac_desc&amp;algo=79</a> &lt;- 트라이 연습 문제 모음</p>



<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>



<script async="" src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5698326622209671" crossorigin="anonymous"></script>
<ins class="adsbygoogle" style="display:block" data-ad-format="autorelaxed" data-ad-client="ca-pub-5698326622209671" data-ad-slot="4245812909"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script>
<p>The post <a href="https://lycos7560.com/etc/%ec%95%8c%ea%b3%a0%eb%a6%ac%ec%a6%98-%ed%8a%b8%eb%9d%bc%ec%9d%b4trie-%ec%9e%90%eb%a3%8c%ea%b5%ac%ec%a1%b0/33961/">알고리즘 – 트라이(Trie) 자료구조</a> appeared first on <a href="https://lycos7560.com">어제와 내일의 나 그 사이의 이야기</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://lycos7560.com/etc/%ec%95%8c%ea%b3%a0%eb%a6%ac%ec%a6%98-%ed%8a%b8%eb%9d%bc%ec%9d%b4trie-%ec%9e%90%eb%a3%8c%ea%b5%ac%ec%a1%b0/33961/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
