<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>for IF</title>
    <link>https://for-if.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Thu, 2 Jul 2026 13:11:56 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>이-프</managingEditor>
    <image>
      <title>for IF</title>
      <url>https://tistory1.daumcdn.net/tistory/5906479/attach/e495dae7cf414fb4a2b18dc3d507edd9</url>
      <link>https://for-if.tistory.com</link>
    </image>
    <item>
      <title>@SpringBootTest, @MockBean, Mockito, Junit 등 테스트에 대해서&amp;hellip;</title>
      <link>https://for-if.tistory.com/116</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;MockMvc?&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;MockMvc란&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MVC에 관련된 Mock 가짜 객체&lt;/li&gt;
&lt;li&gt;웹 어플리케이션을 서버에 배포하지않고, 테스트용 MVC 환경을 만들어서 요청 및 전송, 응답 기능을 제공해주는 객체&lt;/li&gt;
&lt;li&gt;MockMvc를 통해 @Autowired로 주입받아서 사용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;@SpringBootTest&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SpringApplication을 통해서 테스트에서 사용할 ApplicationContext를 쉽게 생성할 수 있습니다.&lt;/li&gt;
&lt;li&gt;그러므로, @SpringBootAplication이 붙은 어노테이션을 찾아 하위의 모든 빈들을 scan하기 때문에 애플리케이션에 정의된 모든 빈을 생성하여 &lt;b&gt;&amp;lsquo;실행 시 느려질 수 있으므로, 단위 테스트에서는 적합하지 않다.&amp;rsquo;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1734242997224&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@SpringBootTest
@AutoConfigureMockMvc //SpringBootTest에서는 MockMvc 객체를 사용하려면 해당 어노테이션 선언 필요
class SpringBootTest {

    @Autowired
    MockMvc mockMvc; // 주입 O
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1734243023894&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@SpringBootTest
@AutoConfigureMockMvc
class SpringBootTest {

    @Autowired
    MockMvc mockMvc; // 주입 O

    @Autowired
    UserController userController; // 주입 O

    @Autowired
    UserRepository userRepository; // 주입 O

    @Autowired
    UserService userService; // 주입 O
}&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;@WebMvcTest&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Web Layer 관련 빈들만 등록하므로, @Component로 등록된 리포지토리와 서비스는 &lt;b&gt;주입이 되지 않는다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Web Layer = Security, Filter, Interceptor, Handling, Controller&lt;/li&gt;
&lt;li&gt;그러므로, 이외는 @MockBean 을 통해 주입받아야한다.&lt;/li&gt;
&lt;li&gt;@MockBean = Spring Application Context에 Mock 객체를 빈으로 등록하는데 사용되는 annotation&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1734243051614&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@WebMvcTest
class SpringBootTest {

		@Autowired
		MockMvc mockMvc; // 주입 O

		@Autowired
		UserController userController; // 주입 O

		//@Autowired
		@MockBean
		UserRepository userRepository; // 주입 X

		//@Autowired
		@MockBean
		UserService userService; // 주입 X
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;928&quot; data-origin-height=&quot;202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Sqi2q/btsLiwtvFEM/430x72LTutsqxQXqDskJiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Sqi2q/btsLiwtvFEM/430x72LTutsqxQXqDskJiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Sqi2q/btsLiwtvFEM/430x72LTutsqxQXqDskJiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSqi2q%2FbtsLiwtvFEM%2F430x72LTutsqxQXqDskJiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;928&quot; height=&quot;202&quot; data-origin-width=&quot;928&quot; data-origin-height=&quot;202&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Java 단위의 Unit Test (단위 테스트)&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JUnit5 : 자바 단위 테스트를 지원하는 &lt;b&gt;&amp;lsquo;테스팅 프레임워크&amp;rsquo;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;AseertJ : .. &lt;b&gt;&amp;lsquo;라이브러리&amp;rsquo;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;given/when/then 패턴&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;given : 어떤 데이터가 준비되었을 때&lt;/li&gt;
&lt;li&gt;when : 어떠한 함수를 실행하면&lt;/li&gt;
&lt;li&gt;then : 어떠한 결과가 나와야한다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Mockito&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자가 동작을 직접 제어할 수 있는 &amp;lsquo;&lt;b&gt;가짜 객체&lt;/b&gt;&amp;rsquo;를 지원하는 &lt;b&gt;테스트 프레임워크&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Spring은 여러 객체들 간의 의존성이 발생하는데, 이러한 의존성은 단위 테스트 작성을 어렵게 한다.&lt;/li&gt;
&lt;li&gt;이를 해결하기 위해, 가짜 객체를 주입시키는 Mockito 라이브러리를 활용할 수 있다.&lt;/li&gt;
&lt;li&gt;가짜 객체에 원하는 결과를 Stub (하향식 테스트) 단위 테스트 가능
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;=&amp;gt; 가짜 객체를 주입하여 어떤 결과를 반환하라고 준비해야함 &amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;doReturn() : 가짜 객체가 특정한 값을 반환하는 경우&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;doNothing() : 가짜 객체가 아무 것도 반환하지 않는 경우 (void)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;doThrow() : 가짜 객체가 예외를 발생시키는 경우&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;@Mock : 가짜 객체를 만들어 반환&lt;/li&gt;
&lt;li&gt;@InjectMocks : 가짜 객체를 자동으로 주입시켜주는 어노테이션&lt;/li&gt;
&lt;li&gt;example) @Mock을 통해 가짜 서비스 생성 후, @InjectMocks 를 통해 Controller에 이를 주입할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SpringBoot 2.2.0부터 공식적으로 JUnit5를 지원함에 따라, 이제부터는 @ExtendedWith(MockitoExtension.class)를 사용해야 결합이 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1734243267233&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Transactional
@ExtendWith(MockitoExtension.class)
class ProductServiceTest {

    @InjectMocks //@Mock으로 생성된 가짜 객체들을 주입받음 (테스트해야할 서비스)
    private ProductService productService; 
    @Mock
    private MemberService memberService;
    @Mock
    private MemberRepository memberRepository;
    @Mock
    private ReservationRepository reservationRepository;
    @Mock
    private ProductRepository productRepository;
    @Mock
    private SecurityUtil securityUtil;&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;각 Layer 별 Test 범위&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Controller&lt;/b&gt;: @WebMvcTest는 &lt;b&gt;웹 계층&lt;/b&gt;을 테스트하며, &lt;b&gt;유닛 테스트&lt;/b&gt;라기보다는 &lt;b&gt;웹 통합 테스트&lt;/b&gt;에 가까운 테스트입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Repository&lt;/b&gt;: @DataJpaTest는 &lt;b&gt;JPA 리포지토리&lt;/b&gt;와 &lt;b&gt;데이터베이스&lt;/b&gt;의 상호작용을 테스트하며, 이는 &lt;b&gt;통합 테스트&lt;/b&gt;에 속합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Service&lt;/b&gt;: @ExtendWith(MockitoExtension.class)와 @Mock을 사용하는 서비스 계층 테스트는 &lt;b&gt;유닛 테스트&lt;/b&gt;로, 비즈니스 로직만 검증하는 데 중점을 둡니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 179px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 36px;&quot;&gt;
&lt;td style=&quot;height: 36px; width: 16.8605%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;height: 36px; width: 21.9767%;&quot;&gt;&lt;b&gt;WebMvcTest&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 36px; width: 32.7908%;&quot;&gt;&lt;b&gt;SpringBootTest&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 36px; width: 28.2557%;&quot;&gt;&lt;b&gt;Junit 단위&lt;/b&gt;(클래스/메소드) 테스트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; width: 16.8605%;&quot;&gt;&lt;b&gt;목적&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; width: 21.9767%;&quot;&gt;&lt;b&gt;&lt;b&gt;웹 계층&lt;/b&gt;&lt;/b&gt;(Controller)만 테스트&lt;/td&gt;
&lt;td style=&quot;height: 17px; width: 32.7908%;&quot;&gt;&lt;b&gt;&lt;b&gt;전체 애플리케이션&lt;/b&gt;&lt;/b&gt;(서비스, 리포지토리 등) 통합 테스트&lt;/td&gt;
&lt;td style=&quot;height: 17px; width: 28.2557%;&quot;&gt;&lt;b&gt;&lt;b&gt;단위&lt;/b&gt;&lt;/b&gt;(클래스/메소드) 테스트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 36px;&quot;&gt;
&lt;td style=&quot;height: 36px; width: 16.8605%;&quot;&gt;&lt;b&gt;테스트 범위&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 36px; width: 21.9767%;&quot;&gt;Controller, 필터 등 웹 관련 구성 요소만 테스트&lt;/td&gt;
&lt;td style=&quot;height: 36px; width: 32.7908%;&quot;&gt;전체 Spring 컨텍스트 로드, 실제 서버 및 DB와 연동 가능&lt;/td&gt;
&lt;td style=&quot;height: 36px; width: 28.2557%;&quot;&gt;특정 클래스나 메소드만 테스트, 외부 의존성 모킹&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;height: 18px; width: 16.8605%;&quot;&gt;&lt;b&gt;속도&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 18px; width: 21.9767%;&quot;&gt;빠름, 웹 계층만 로드&lt;/td&gt;
&lt;td style=&quot;height: 18px; width: 32.7908%;&quot;&gt;느림, 전체 애플리케이션 로드&lt;/td&gt;
&lt;td style=&quot;height: 18px; width: 28.2557%;&quot;&gt;매우 빠름, 독립적 테스트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 36px;&quot;&gt;
&lt;td style=&quot;height: 36px; width: 16.8605%;&quot;&gt;&lt;b&gt;주요 사용 목적&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 36px; width: 21.9767%;&quot;&gt;HTTP 요청과 응답 처리 테스트 (컨트롤러 테스트)&lt;/td&gt;
&lt;td style=&quot;height: 36px; width: 32.7908%;&quot;&gt;애플리케이션 전체 통합 동작 테스트 &lt;br /&gt;(서비스, DB 등)&lt;/td&gt;
&lt;td style=&quot;height: 36px; width: 28.2557%;&quot;&gt;특정 비즈니스 로직, 메소드 동작 검증&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 36px;&quot;&gt;
&lt;td style=&quot;height: 36px; width: 16.8605%;&quot;&gt;&lt;b&gt;외부 의존성&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 36px; width: 21.9767%;&quot;&gt;외부 서비스는 @MockBean을 사용하여 모킹&lt;/td&gt;
&lt;td style=&quot;height: 36px; width: 32.7908%;&quot;&gt;실제 DB 및 외부 시스템과 통합될 수 있음&lt;/td&gt;
&lt;td style=&quot;height: 36px; width: 28.2557%;&quot;&gt;외부 의존성은 모킹하여 격리&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description>
      <category>BACKEND/JAVA &amp;amp; SPRING</category>
      <category>JUnit</category>
      <category>MockBean</category>
      <category>mockito</category>
      <category>MockMvc</category>
      <category>springboot</category>
      <category>SpringBootTest</category>
      <author>이-프</author>
      <guid isPermaLink="true">https://for-if.tistory.com/116</guid>
      <comments>https://for-if.tistory.com/116#entry116comment</comments>
      <pubDate>Sun, 15 Dec 2024 15:15:48 +0900</pubDate>
    </item>
    <item>
      <title>[백준][자바] 1149 - RGB거리 - DP</title>
      <link>https://for-if.tistory.com/115</link>
      <description>&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  문제&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;백준 | RGB거리 | SILVER 1 | DP&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1149&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/1149&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  문제 탐색하기&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;RGB 거리에는 집이 N개 존재
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;거리는 &amp;lsquo;선분&amp;rsquo;&lt;/li&gt;
&lt;li&gt;1~N번 집 존재&lt;/li&gt;
&lt;li&gt;빨, 초, 파 중 하나의 색&lt;/li&gt;
&lt;/ul&gt;
&amp;rArr; &lt;b&gt;각 비용이 존재할 때, 모든 집을 칠하는 비용의 MIN 값 구하기&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;규칙&lt;/b&gt; :
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1번 집 색상 &amp;ne; 2번 집 색상&lt;/li&gt;
&lt;li&gt;N번 집 색상 &amp;ne; N-1번 집 색상&lt;/li&gt;
&lt;li&gt;i 번 집 색상 &amp;ne; i-1 (2&amp;le;i&amp;le;n-1)&lt;/li&gt;
&lt;li&gt;i 번 집 색상 &amp;ne; i+1 (2&amp;le;i&amp;le;n-1)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;입력&lt;/b&gt; :
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;N (집의 수)&lt;/li&gt;
&lt;li&gt;집을 빨, 초, 파로 칠하는 비용 (1~N번 순서로)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;출력&lt;/b&gt; :
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 집을 칠하는 비용의 MIN 값&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  알고리즘&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이전의 계산 결과가 이 후의 계산에 영향을 주므로, &lt;b&gt;DP를 활용&lt;/b&gt;해서 문제를 풀어야한다.&lt;/li&gt;
&lt;li&gt;DP를 풀땐, 규칙이 가장 중요한데&amp;hellip;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 문제에서는 빨, 초, 파 3가지 경우가 존재하므로 3가지 모두 선정된다는 가정 하에 계산을 모두 진행하면서&lt;/li&gt;
&lt;li&gt;최종 행의 MIN값이 답이 될 것이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;310&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C4de6/btsK9Ptjb5E/EIKdYeS2FWdw56wARu3Enk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C4de6/btsK9Ptjb5E/EIKdYeS2FWdw56wARu3Enk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C4de6/btsK9Ptjb5E/EIKdYeS2FWdw56wARu3Enk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC4de6%2FbtsK9Ptjb5E%2FEIKdYeS2FWdw56wARu3Enk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;525&quot; height=&quot;310&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;310&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;351&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CWsQC/btsLalMcEiB/mnfWrve0nT95Rw20JOMGk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CWsQC/btsLalMcEiB/mnfWrve0nT95Rw20JOMGk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CWsQC/btsLalMcEiB/mnfWrve0nT95Rw20JOMGk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCWsQC%2FbtsLalMcEiB%2FmnfWrve0nT95Rw20JOMGk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;566&quot; height=&quot;351&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;351&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;b&gt; 즉, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;자기자신을 기준으로 나머지 2개에서 최소값을 더하면서 열3을 갱신해 나아가야한다. &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  코드 설계하기&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;n, rgb, dp 초기화&lt;/li&gt;
&lt;li&gt;rgb 배열 입력&lt;/li&gt;
&lt;li&gt;dp 배열 입력 (rgb 자기자신 + 이전 행의 다른 열 중 최소값)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt; &lt;span&gt; &lt;/span&gt; 시도 회차 수정 사항&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1회차&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;배열의 크기를 처음에는 n으로 잡으니, 0일때 이전의 값을 불러 올 수 없어 문제가 발생했음 &amp;rarr; n+1로 행의 크기를 넓히기&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  정답 코드&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1733624282086&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        int n = Integer.parseInt(br.readLine());
        int[][] rgb = new int[n+1][3];
        int[][] dp = new int[n+1][3];

        for(int i = 1; i&amp;lt;=n; i++){
            st = new StringTokenizer(br.readLine());
            for(int j = 0; j&amp;lt;3; j++){
                rgb[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        for(int i = 1; i&amp;lt;=n; i++){
            dp[i][0] = rgb[i][0] + Math.min(dp[i-1][1], dp[i-1][2]);
            dp[i][1] = rgb[i][1] + Math.min(dp[i-1][0], dp[i-1][2]);
            dp[i][2] = rgb[i][2] + Math.min(dp[i-1][0], dp[i-1][1]);
        }

        int answer = Math.min(dp[n][0], dp[n][1]);
        answer = Math.min(answer, dp[n][2]);

        System.out.println(answer);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;DP 문제에서는 은근히 배열의 크기가 중요할 때가 많은 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;문제에 나온 예시를 근거로 차근차근 풀어보잣  &lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/백준</category>
      <category>1149</category>
      <category>DP</category>
      <category>RGB거리</category>
      <category>백준</category>
      <author>이-프</author>
      <guid isPermaLink="true">https://for-if.tistory.com/115</guid>
      <comments>https://for-if.tistory.com/115#entry115comment</comments>
      <pubDate>Sun, 8 Dec 2024 11:19:25 +0900</pubDate>
    </item>
    <item>
      <title>[백준][자바] 14430 - 자원캐기 - DP</title>
      <link>https://for-if.tistory.com/114</link>
      <description>&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  문제&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;백준 | 자원캐기 | SILVER 2 | DP&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14430&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/14430&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  문제 탐색하기&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;제한된 범위 내에서 자원을 탐색&lt;/li&gt;
&lt;li&gt;(1,1) 부터 (N,M)까지 자원을 탐색&lt;/li&gt;
&lt;li&gt;오른쪽, 아래쪽으로 한칸 이동 가능&lt;/li&gt;
&lt;li&gt;(x,y)에 자원이 있는 경우에만 해당 자원을 채취 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;입력&lt;/b&gt; :
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;n (세로길이 = 행), m(가로길이 = 열)&lt;/li&gt;
&lt;li&gt;n행 m열에 걸쳐 탐사영역&lt;/li&gt;
&lt;li&gt;자원 = 1, 땅 = 0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;출력&lt;/b&gt; : 탐색할 수 있는 자원의 최대 숫자를 구하기&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  알고리즘&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;N과 M이 최대 300이므로, 땅의 크기는 최대 90000까지 가능&lt;/li&gt;
&lt;li&gt;만약, 완전탐색으로 접근할 경우, N,M까지 가는 경우 O(300^2) + 최대 가지의 수임&lt;/li&gt;
&lt;li&gt;DP를 통해서, 최대 광석의 개수를 계속해서 업데이트한다면?&lt;/li&gt;
&lt;li&gt;example) &lt;span style=&quot;background-color: #dddddd;&quot;&gt;DP[i][j] =grid[i][j] + Math.max(DP[i][j-1], DP[i-1][j])&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;309&quot; data-origin-height=&quot;214&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxaogO/btsK9ykLQ3Q/LZEQYzJAEMEcjOwtxZTPI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxaogO/btsK9ykLQ3Q/LZEQYzJAEMEcjOwtxZTPI1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxaogO/btsK9ykLQ3Q/LZEQYzJAEMEcjOwtxZTPI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxaogO%2FbtsK9ykLQ3Q%2FLZEQYzJAEMEcjOwtxZTPI1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;309&quot; height=&quot;214&quot; data-origin-width=&quot;309&quot; data-origin-height=&quot;214&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  코드 설계하기&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;n,m, grid 입력&lt;/li&gt;
&lt;li&gt;dp 갱신 (&lt;span style=&quot;background-color: #dddddd;&quot;&gt;DP[i][j] =grid[i][j] + Math.max(DP[i][j-1], DP[i-1][j])&lt;/span&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, i-1과 j-1이 계산에 필요하므로 기존 n,m보단 +1씩 큰 배열을 만들어서 outOfRange 에러를 방지한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  정답 코드&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1733543511876&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.*;
import java.io.*;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        st = new StringTokenizer(br.readLine());
        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());

        int[][] grid = new int[n+1][m+1];
        int[][] dp = new int[n+1][m+1];

        for(int i = 1; i&amp;lt;=n; i++){
            st = new StringTokenizer(br.readLine());
            for(int j = 1; j&amp;lt;=m; j++){
                grid[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        for(int i = 1; i &amp;lt;= n; i++){
            for(int j = 1; j&amp;lt;=m; j++){
                dp[i][j] = grid[i][j] + Math.max(dp[i][j-1], dp[i-1][j]);
            }
        }

        System.out.println(dp[n][m]);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;이전에 프로그래머스에서도 이와 비슷한 문제를 풀었던 기억이 난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;DP는 코드보단 알고리즘 생각에 대한 문제이니, 잘 복습해두자 !!  &lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/백준</category>
      <category>14430</category>
      <category>DP</category>
      <category>백준</category>
      <category>자원캐기</category>
      <author>이-프</author>
      <guid isPermaLink="true">https://for-if.tistory.com/114</guid>
      <comments>https://for-if.tistory.com/114#entry114comment</comments>
      <pubDate>Sat, 7 Dec 2024 12:53:28 +0900</pubDate>
    </item>
    <item>
      <title>[백준][자바] 9095 - 1, 2, 3 더하기 - DP</title>
      <link>https://for-if.tistory.com/113</link>
      <description>&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  문제&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;백준 | 1, 2, 3 더하기 | SILVER 3 | DP&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/9095&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/9095&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  문제 탐색하기&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;n이 있을 때, 1,2,3의 합으로 나타내는 방법의 수를 찾기&lt;/li&gt;
&lt;li&gt;합은 1개 이상 사용해야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  알고리즘&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;방법이 존재하는 경우들을 모두 세야하므로, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;DP를 활용&lt;/b&gt;&lt;/span&gt;해야한다.&lt;/li&gt;
&lt;li&gt;DP는 그 이전의 결과값을 바탕으로 쓸 수 있으므로, 해당 값을 이용해야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;796&quot; data-origin-height=&quot;817&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baMEGL/btsLanOUTWp/n60ZTjtXWkn3xsI95ZPwoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baMEGL/btsLanOUTWp/n60ZTjtXWkn3xsI95ZPwoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baMEGL/btsLanOUTWp/n60ZTjtXWkn3xsI95ZPwoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaMEGL%2FbtsLanOUTWp%2Fn60ZTjtXWkn3xsI95ZPwoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;796&quot; height=&quot;817&quot; data-origin-width=&quot;796&quot; data-origin-height=&quot;817&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DP[0] = 0&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DP[1] = 1&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DP[2] = 2&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DP[3] = 4&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DP[4] = 7 (=1+2+4)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DP[5] = 13 (=2+4+7)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DP[6] = 24 (=4+7+13)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DP[7] = 44 (=7+13+24)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DP[10] = 274&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, &lt;b&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;DP[i] = DP[i-1] + DP[i-2] +DP[i-3] (i ≽ 4)&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  코드 설계하기&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;t, 케이스 입력&lt;/li&gt;
&lt;li&gt;dp 배열 구현&lt;/li&gt;
&lt;li&gt;t 케이스에 따른 답변 출력&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  정답 코드&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1733446364745&quot; class=&quot;java&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main{

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int t = Integer.parseInt(br.readLine());

        int[] dp = new int[12];
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 4;

        for (int i = 4; i &amp;lt; 12; i++) {
            dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
        }

        for (int i = 0; i &amp;lt; t; i++) {
            int num = Integer.parseInt(br.readLine());
            System.out.println(dp[num]);
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;이전에 풀어봤던 문제랑 비슷해서, 생각보다 빠르게 풀 수 있었다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;DP는 진짜.. 알고리즘 싸움보단 수학적 사고를 어떻게 빠르게 하냐의 싸움인 것 같아 문제를 많이 풀어야겠다  &lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/백준</category>
      <category>9095</category>
      <category>DP</category>
      <category>백준</category>
      <category>실버</category>
      <author>이-프</author>
      <guid isPermaLink="true">https://for-if.tistory.com/113</guid>
      <comments>https://for-if.tistory.com/113#entry113comment</comments>
      <pubDate>Fri, 6 Dec 2024 09:58:08 +0900</pubDate>
    </item>
    <item>
      <title>[백준][자바] 10026 - 적록색약 - BFS(완전탐색)</title>
      <link>https://for-if.tistory.com/112</link>
      <description>&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  문제&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;백준 | 적록색약 | GOLD 5 | 완전탐색&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/10026&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/10026&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  문제 탐색하기&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;N*N크기의 그리드
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;R, G, B 가 그리드에 존재&lt;/li&gt;
&lt;li&gt;구역이 나뉘어 있고, 같은 색으로 있음&lt;/li&gt;
&lt;li&gt;같은 색상이 상하좌우로 인접 &amp;rArr; 두 글자는 같은 구역에 속함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;적록색약 = 빨간색과 초록색의 차이를 거의 느끼지 못함 (빨강과 초록을 하나로 보는 것)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;example)&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;RRRBB
GGBBB
BBBRR
BBRRR
RRRRR
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;적록색약 x = 4구역&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;적록색약 o = 3구역&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;출력&lt;/b&gt; : 적록색약 아닌 사람이 본 구역의 수, 적록색약인 사람이 본 구역의 수&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  알고리즘&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;적록색약 및 적록색약 x 사람이 보는 색의 구역을 모두 확인해야하므로, &lt;b&gt;&amp;lsquo;BFS&amp;rsquo; 완전탐색&lt;/b&gt;을 사용한다.&lt;/li&gt;
&lt;li&gt;N이 100이하이므로, 2차배열을 사용하는 BFS에서 100 ^ 2 &amp;le; 1초 로 BFS 알고리즘이 사용 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  코드 설계하기&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;N, 그리드 입력&lt;/li&gt;
&lt;li&gt;완전탐색 BFS 코드 구현
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;코드 구현은 여느 BFS 문제나 같음 BUT, canGo메소드의 차이 존재&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  시도 회차 수정&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1회차&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;적록색약 grid를 g 제외하고 나머지일 경우, 똑같이 grid에 입력받도록 해야하는데, 이부분을 제외시켰다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  수정 후, 정답 코드&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1733361913235&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;


public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        int n = Integer.parseInt(br.readLine());

        String[][] gridDiff = new String[n][n]; //적록색약 x
        String[][] gridDiffNo = new String[n][n]; //적록색약 o
        int[][] visited = new int[n][n];
        for (int i = 0; i &amp;lt; n; i++) {
            String line = br.readLine();
            for (int j = 0; j &amp;lt; n; j++) {
                String color = String.valueOf(line.charAt(j));
                gridDiff[i][j] = color;
                if (color.equals(&quot;G&quot;)) {
                    gridDiffNo[i][j] = &quot;R&quot;;
                } else {
                    gridDiffNo[i][j] = color;
                }
            }
        }

        String[] color = {&quot;R&quot;, &quot;G&quot;, &quot;B&quot;};
        int redGreenDiff = 0; //적록색약 x
        for (String c : color) {
            for (int i = 0; i &amp;lt; n; i++) {
                for (int j = 0; j &amp;lt; n; j++) {
                    if (gridDiff[i][j].equals(c) &amp;amp;&amp;amp; visited[i][j] == 0) {
                        bfs(i, j, gridDiff, visited);
                        redGreenDiff++;
                    }
                }
            }
        }

        color = new String[]{&quot;R&quot;, &quot;B&quot;};
        visited = new int[n][n];
        int redGreenSame = 0; //적록색약 o
        for (String c : color) {
            for (int i = 0; i &amp;lt; n; i++) {
                for (int j = 0; j &amp;lt; n; j++) {
                    if (gridDiffNo[i][j].equals(c) &amp;amp;&amp;amp; visited[i][j] == 0) {
                        bfs(i, j, gridDiffNo, visited);
                        redGreenSame++;
                    }
                }
            }
        }


        System.out.print(redGreenDiff + &quot; &quot; + redGreenSame);


    }

    public static void bfs(int x, int y, String[][] grid, int[][] visited) {
        int[] dx = {-1, 1, 0, 0};
        int[] dy = {0, 0, -1, 1};

        Queue&amp;lt;GridPoint&amp;gt; queue = new LinkedList&amp;lt;&amp;gt;();
        queue.offer(new GridPoint(x, y));
        visited[x][y] = 1;

        while (!queue.isEmpty()) {
            GridPoint cur = queue.poll();

            for (int i = 0; i &amp;lt; 4; i++) {
                int nx = cur.x + dx[i];
                int ny = cur.y + dy[i];

                if (canGo(nx, ny, grid, visited, grid[cur.x][cur.y])) {
                    queue.offer(new GridPoint(nx, ny));
                    visited[nx][ny] = 1;
                }
            }
        }
    }

    public static boolean canGo(int x, int y, String[][] grid, int[][] visited, String color) {
        if (x &amp;lt; 0 || x &amp;gt;= grid.length || y &amp;lt; 0 || y &amp;gt;= grid[0].length) {
            return false;
        } else if (visited[x][y] == 1 || !grid[x][y].equals(color)) {
            return false;
        }
        return true;
    }

}

class GridPoint {
    int x;
    int y;

    public GridPoint(int x, int y) {
        this.x = x;
        this.y = y;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;GOLD 5여서 처음엔 조금 두려웠지만, 어쨌든 BFS 문제는 정형화되어있어서 풀이가 상대적으로 쉬웠다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;다만, 시간 복잡도 면에서 적록색약 유무의 코드를 병합시키는 리팩토링이 필요할 듯 하다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/백준</category>
      <category>10026</category>
      <category>BFS</category>
      <category>Gold</category>
      <category>백준</category>
      <category>완전탐색</category>
      <category>적록색약</category>
      <author>이-프</author>
      <guid isPermaLink="true">https://for-if.tistory.com/112</guid>
      <comments>https://for-if.tistory.com/112#entry112comment</comments>
      <pubDate>Thu, 5 Dec 2024 10:26:53 +0900</pubDate>
    </item>
    <item>
      <title>[백준][자바] 27737 - 버섯농장 - BFS(완전탐색)</title>
      <link>https://for-if.tistory.com/111</link>
      <description>&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  문제&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;백준 | 버섯농장 | SILVER 1 | 완전탐색&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/27737&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/27737&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt; &amp;nbsp;문제 탐색하기&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;N * N 칸으로 이루어진 나무판
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;버섯이 자랄 수 있는 칸&lt;/li&gt;
&lt;li&gt;버섯이 자랄 수 없는 칸&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;M개의 버섯포자 (자랄 수 있는 칸에 배치)&lt;/li&gt;
&lt;li&gt;포자가 심어진 칸을 포함해 최대 K개의 연결된 칸에 버섯이 자람
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상하좌우로 적어도 한 변을 공유하는 칸들&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;한 칸에 여러개 겹쳐서 심을 수 있음&lt;/li&gt;
&lt;li&gt;ex) x개의 버섯 포자 겹쳐서 = x * K개의 연결된 칸에 버섯&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;입력&lt;/b&gt; : N(크기), M(버섯 포자 개수), K(연결)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;0 : 버섯 자랄 수 O&lt;/li&gt;
&lt;li&gt;1 : 버섯 자랄수 X&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;출력&lt;/b&gt; : 농사가 가능할 경우, 남은 버섯 포자의 개수
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;농사 가능 = 버섯이 자랄 수 있는 모든 칸에 버섯이 전부 자랐을 때 농사가 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  알고리즘&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나무 판에서 &amp;lsquo;버섯이 자랄 수 있는&amp;rsquo; 공간들을 연결하는 것이 핵심이므로, &lt;span style=&quot;background-color: #f6e199; color: #000000;&quot; data-token-index=&quot;1&quot;&gt;완전탐색(BFS)&lt;/span&gt;을 통해 방문하는 것이 적합하다고 판단했습니다.&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  코드 설계하기&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;N,M,K 입력&lt;/li&gt;
&lt;li&gt;배열 입력 초기화 (grid)&lt;/li&gt;
&lt;li&gt;BFS 로직 작성
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Queue를 활용하여 상하좌우 이동한 노드들 연결&lt;/li&gt;
&lt;li&gt;다만, 이동 시 grid를 벗어나지 않는지 및 재방문하지 않는 노드인지 확인 필요&lt;/li&gt;
&lt;li&gt;문제에서 땅의 크기를 k로 나눠서 이를 &amp;lsquo;올림&amp;rsquo;한 값을 M에서 제거하므로 땅의 크기를 return (size)&lt;/li&gt;
&lt;/ol&gt;
ex) 예를들어 땅의 크기 4, K 3이면 최소 2개의 포자가 필요 : 4/3 = 1.3333 (올림 &amp;rarr; 2)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;반환받은 size를 바탕으로 최소 1개의 포자사용 여부 파악
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;사용 시, possible &amp;amp; m - size&lt;/li&gt;
&lt;li&gt;사용 x , impossible&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  시도 회차 수정&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1회차&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;문제에서 &lt;b&gt;'버섯 포자를 하나라도 사용하고'&lt;/b&gt;&amp;nbsp;라는 조건이 있었는데 이 조건을 놓쳐서 틀렸음을 확인함&lt;/li&gt;
&lt;li&gt;&amp;rArr; flag를 추가해서 포자 사용 여부를 체크해야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733296016031&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;###틀린 1차 코드###
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        st = new StringTokenizer(br.readLine());

        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
        int k = Integer.parseInt(st.nextToken());

        int[][] grid = new int[n][n];
        int[][] visited = new int[n][n];
        for (int i = 0; i &amp;lt; n; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j &amp;lt; n; j++) {
                grid[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        for (int i = 0; i &amp;lt; n; i++) {
            for (int j = 0; j &amp;lt; n; j++) {
                if (grid[i][j] == 0 &amp;amp;&amp;amp; visited[i][j] == 0) {
                    double size = bfs(i, j, visited, grid);
                    size = (int) Math.ceil(size / k);
                    m -= size;
                }
            }
        }

        if(m &amp;gt;=0){
            System.out.println(&quot;POSSIBLE&quot;);
            System.out.println(m);
        } else {
            System.out.println(&quot;IMPOSSIBLE&quot;);
        }
    }

    public static double bfs(int x, int y, int[][] visited, int[][] grid) {
        int[] dx = {-1, 1, 0, 0};
        int[] dy = {0, 0, -1, 1};

        Queue&amp;lt;Point&amp;gt; queue = new LinkedList&amp;lt;&amp;gt;();
        queue.offer(new Point(x,y));
        visited[x][y] = 1;

        int size = 1;
        while(!queue.isEmpty()){
            Point cur = queue.poll();

            for(int i = 0; i&amp;lt;4; i++){
                int nx = cur.x + dx[i];
                int ny = cur.y + dy[i];

                if(canGo(nx, ny, grid, visited)){
                    visited[nx][ny] = 1;
                    queue.offer(new Point(nx, ny));
                    size++;
                }
            }
        }
        return size;
    }

    public static boolean canGo(int x, int y, int[][] grid, int[][] visited){
        if(x &amp;lt; 0 || x &amp;gt;= grid.length || y &amp;lt; 0 || y &amp;gt;= grid[0].length){
            return false;
        } else if(grid[x][y] == 1 || visited[x][y] == 1){
            return false;
        }
        return true;
    }
}


class Point {
    int x;
    int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  정답 코드&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1733295841029&quot; class=&quot;java&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        st = new StringTokenizer(br.readLine());

        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
        int k = Integer.parseInt(st.nextToken());

        int[][] grid = new int[n][n];
        int[][] visited = new int[n][n];
        for (int i = 0; i &amp;lt; n; i++) {
            st = new StringTokenizer(br.readLine());
            for (int j = 0; j &amp;lt; n; j++) {
                grid[i][j] = Integer.parseInt(st.nextToken());
            }
        }

        boolean isChanged = false;
        for (int i = 0; i &amp;lt; n; i++) {
            for (int j = 0; j &amp;lt; n; j++) {
                if (grid[i][j] == 0 &amp;amp;&amp;amp; visited[i][j] == 0) {
                    double size = bfs(i, j, visited, grid);
                    size = (int) Math.ceil(size / k);
                    m -= size;
                    isChanged = true;
                }
            }
        }

        if(isChanged &amp;amp;&amp;amp; m &amp;gt;=0){
            System.out.println(&quot;POSSIBLE&quot;);
            System.out.println(m);
        } else {
            System.out.println(&quot;IMPOSSIBLE&quot;);
        }
    }

    public static double bfs(int x, int y, int[][] visited, int[][] grid) {
        int[] dx = {-1, 1, 0, 0};
        int[] dy = {0, 0, -1, 1};

        Queue&amp;lt;Point&amp;gt; queue = new LinkedList&amp;lt;&amp;gt;();
        queue.offer(new Point(x,y));
        visited[x][y] = 1;

        int size = 1;
        while(!queue.isEmpty()){
            Point cur = queue.poll();

            for(int i = 0; i&amp;lt;4; i++){
                int nx = cur.x + dx[i];
                int ny = cur.y + dy[i];

                if(canGo(nx, ny, grid, visited)){
                    visited[nx][ny] = 1;
                    queue.offer(new Point(nx, ny));
                    size++;
                }
            }
        }
        return size;
    }

    public static boolean canGo(int x, int y, int[][] grid, int[][] visited){
        if(x &amp;lt; 0 || x &amp;gt;= grid.length || y &amp;lt; 0 || y &amp;gt;= grid[0].length){
            return false;
        } else if(grid[x][y] == 1 || visited[x][y] == 1){
            return false;
        }
        return true;
    }
}


class Point {
    int x;
    int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;최근에 bfs 문제를 계속 풀고 있는데, 문제는 정형화되어 있으므로 반복된 풀이가 필요할 듯 하다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다만, 이번 문제에서 '1번 이상의 사용' 과 같은 트릭이 있을 수 있으니, 문제를 구체적으로 읽는 연습을 통해 실수를 줄이는 것이 필요할 것 같다.  ⭐&lt;/p&gt;</description>
      <category>알고리즘/백준</category>
      <category>27737</category>
      <category>BFS</category>
      <category>silver</category>
      <category>백준</category>
      <category>버섯농장</category>
      <category>완전탐색</category>
      <author>이-프</author>
      <guid isPermaLink="true">https://for-if.tistory.com/111</guid>
      <comments>https://for-if.tistory.com/111#entry111comment</comments>
      <pubDate>Wed, 4 Dec 2024 16:09:06 +0900</pubDate>
    </item>
    <item>
      <title>[백준][자바] 1326 - 폴짝폴짝 - BFS(완전탐색)</title>
      <link>https://for-if.tistory.com/110</link>
      <description>&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;  문제&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;백준 | 폴짝폴짝 | SILVER 2 | 완전탐&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1326&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/1326&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt; &amp;nbsp;문제 탐색하기&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;징검다리에 숫자 존재&lt;/li&gt;
&lt;li&gt;징검다리에 쓰여 있는 수의 배수만큼 떨어져 있는 곳으로 감&lt;/li&gt;
&lt;li&gt;a번째 징검다리에서 b번째 징검다리로 이동&lt;/li&gt;
&lt;li&gt;&lt;b&gt;출력&lt;/b&gt; : 최소 몇 번 점프를 하여 b번까지 가는지&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;  알고리즘&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;lsquo;최소&amp;rsquo; 의 점프를 구해야하므로, 완전탐색(DFS/BFS)를 사용할 예정
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DP와 같은 경우에는 &amp;lsquo;누적&amp;rsquo;된 정보들을 바탕으로 풀어야하는데, 이전 상태값에 의존하는 것은 아니므로 DP로 하지 않아도 될 것이라 생각했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;징검다리의 개수 N이 10,000까지 존재하므로 O(N^2) = 100,000,000 &amp;lt; 2초 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;  코드 설계하기&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;N, A, B 입력받기&lt;/li&gt;
&lt;li&gt;BFS를 통해
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;앞으로 가는 경우&lt;/li&gt;
&lt;li&gt;뒤로 가는 경우&lt;/li&gt;
&lt;/ol&gt;
&amp;rarr; 2가지 방법으로 가능한 경우들을 Queue에 입력받도록 구현&lt;/li&gt;
&lt;li&gt;(2 방법 모두 visited를 활용해서 이미 지나간 돌은 제외한다.)&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;  정답 코드&lt;/h4&gt;
&lt;pre id=&quot;code_1733118173780&quot; class=&quot;java&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.*;
import java.io.*;

public class Main {
    static int n;
    static int[] stones;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        int answer = 1;

        n = Integer.parseInt(br.readLine());

        stones = new int[n+1];
        st = new StringTokenizer(br.readLine());

        for(int i = 1; i&amp;lt;n+1; i++){
            stones[i] = Integer.parseInt(st.nextToken());
        }

        String[] ab = br.readLine().split(&quot; &quot;);

        int a = Integer.parseInt(ab[0]);
        int b = Integer.parseInt(ab[1]);

        System.out.println(bfs(a,b));

    }

    public static int bfs(int start, int end){
        int[] visited = new int[n+1];

        visited[start] = 1;

        Queue&amp;lt;Frog&amp;gt; queue = new LinkedList&amp;lt;&amp;gt;();

        queue.offer(new Frog(start, 0));

        while(!queue.isEmpty()){
            Frog frog = queue.poll();

            if(frog.pos == end){
                return frog.cnt;
            }

            int jump = stones[frog.pos];

            //앞으로가는경우
            for(int i = frog.pos; i&amp;lt; n+1; i+= jump){
                if(visited[i] == 1){
                    continue;
                }
                visited[i] = 1;
                queue.offer(new Frog(i, frog.cnt+1));
            }

            //뒤로가는경우
            for(int i = frog.pos; i&amp;gt;=1; i-= jump){
                if(visited[i] == 1){
                    continue;
                }
                visited[i] = 1;
                queue.offer(new Frog(i, frog.cnt + 1));
            }

        }
        return -1;

    }
}

class Frog {
    int pos;
    int cnt;

    public Frog(int pos, int cnt){
        this.pos = pos;
        this.cnt = cnt;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 뭔가 '최소' 라는 키워드에 꽂혀서 BFS인것은 눈치를 챘으나.. 확연하게 문제 푸는 방식이 떠오르지 않아 당황했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 A B 우리 뇌리속에선 A가 먼저, B가 이후인데 이에 대한 정보도 문제에선 주어지지 않았으니 ..... (당황)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로는 문제 접근을 할 때 내 상상보단, '문제'에 집중을 해야겠다  &lt;/p&gt;</description>
      <category>알고리즘/백준</category>
      <category>1326</category>
      <category>BFS</category>
      <category>백준</category>
      <category>완전탐색</category>
      <category>폴짝폴짝</category>
      <author>이-프</author>
      <guid isPermaLink="true">https://for-if.tistory.com/110</guid>
      <comments>https://for-if.tistory.com/110#entry110comment</comments>
      <pubDate>Mon, 2 Dec 2024 14:46:52 +0900</pubDate>
    </item>
    <item>
      <title>[백준][JAVA] 1713 - 후보 추천하기 - 시뮬레이션</title>
      <link>https://for-if.tistory.com/109</link>
      <description>&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;  문제&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;백준 | 후보 추천하기 | SILVER 1 | 시뮬레이션&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1713&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/1713&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt; &amp;nbsp;문제 탐색하기&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;학생회장 후보 = 일정기간동안 전체 학생의 추천 수&lt;/li&gt;
&lt;li&gt;홈페이지 사진틀의 수 = 후보의 수
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 사진틀 empty&lt;/li&gt;
&lt;li&gt;어떤 학생 &amp;rarr; 특정 학생 추천 : 추천받은 학생이 사진틀에 게시&lt;/li&gt;
&lt;li&gt;모두 full &amp;rarr; 추천받은 횟수가 가장 적은 학생의 사진을 삭제 &amp;amp; 새롭게 추천받은 학생 게시 (OS 페이징 기법 중, LFU)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;만약, 2명 이상 = 게시된 지 가장 오래된 사진을 삭제(OS 페이징 기법중, LRU)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;게시된 학생이 다른 학생의 추천을 &amp;lsquo;또&amp;rsquo; 받으면, 추천 횟수 +1&lt;/li&gt;
&lt;li&gt;if 삭제되는 경우 = 추천횟수는 0으로 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;출력 : 최종 후보 (제일 추천이 많은 후보)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;i&gt;example)&lt;/i&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2 1 4 3 5 6 2 7 2&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2 0 0&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2 1 0&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2 1 4&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1 4 3&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4 3 5&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3 5 6&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5 6 2&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6 2 7&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6 2 7 (받은 개수 : 1,2,1)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rArr; 출력 : 2, 6, 7 (오름차순으로 표현)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;  알고리즘&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;N &amp;le; 20&lt;/li&gt;
&lt;li&gt;총 추천횟수 &amp;le;1000&lt;/li&gt;
&lt;li&gt;학생번호 &amp;le;100&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rArr; 20 * 1000 * 100 = 1초 이내로 가능할 듯!&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체를 먼저 만든다 (횟수 cnt, 사진에 등록된 시간(오래됨을 판별))&lt;/li&gt;
&lt;li&gt;이를 바탕으로 PriorityQueue를 이용해서 매번 sorting을 진행해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;  시도 회차 수정 사항&lt;/h4&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  1회차&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;런타임에러 발생&lt;/li&gt;
&lt;li&gt;그도그럴것이&amp;hellip; queue를 막상 사용해보니 너무 비효율적임
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;매번 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;time을 +1해주는 것&lt;/b&gt;&lt;/span&gt;과 num을 찾아 돌리고 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;다시 넣어주는 것이 비효율적&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;b&gt;&amp;rArr; cntPlus와 timePlus 메소드 변경 필요&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1732864537669&quot; class=&quot;java&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;import java.util.*;
import java.io.*;


public class q1713_silver1 {

    static PriorityQueue&amp;lt;Person&amp;gt; pq = new PriorityQueue&amp;lt;&amp;gt;((o1,o2) -&amp;gt; {
        if(o1.cnt != o2.cnt){
            return o1.cnt - o2.cnt;
        } else {
            return o2.time - o1.time;
        }
    });

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        int n = Integer.parseInt(br.readLine());
        int cnt = Integer.parseInt(br.readLine());
        st = new StringTokenizer(br.readLine());
        for(int i = 0; i&amp;lt;cnt; i++){
            int person = Integer.parseInt(st.nextToken());
            if(!cntPlus(person)) {
                if(pq.size() == n){
                    pq.poll();
                    pq.offer(new Person(person, 1, 0));
                } else {
                    pq.offer(new Person(person, 1, 0));
                }
            }
            timePlus();
        }


        List&amp;lt;Person&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();
        while(!pq.isEmpty()){
            Person person = pq.poll();
            list.add(person);
        }

        Collections.sort(list, (o1, o2) -&amp;gt; o1.num - o2.num);

        for(Person p : list){
            System.out.print(p.num + &quot; &quot;);
        }
    }

    public static boolean cntPlus(int num){
        Queue&amp;lt;Person&amp;gt; queue = new LinkedList&amp;lt;&amp;gt;();
        boolean isCntChanged = false;
        while(!pq.isEmpty()){
            Person person = pq.poll();
            if(person.num == num){
                queue.offer(new Person(person.num, person.cnt+1, person.time));
                isCntChanged = true;
            } else {
                queue.offer(person);
            }
        }

        while(!queue.isEmpty()){
            pq.offer(queue.poll());
        }

        return isCntChanged;
    }

    public static void timePlus(){
        Queue&amp;lt;Person&amp;gt; queue = new LinkedList&amp;lt;&amp;gt;();
        while(!pq.isEmpty()){
            Person person = pq.poll();
            queue.offer(new Person(person.num, person.cnt, person.time+1));
        }

        while(!queue.isEmpty()){
            pq.offer(queue.poll());
        }
    }
}

class Person  {
    int num;
    int cnt;
    int time;

    public Person(int num, int cnt, int time){
        this.num = num;
        this.cnt = cnt;
        this.time = time;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  2회차 변경사항&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;List&amp;lt;Person&amp;gt; tmpList = new ArrayList&amp;lt;&amp;gt;(pq);&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=&amp;gt; PriorityQueue와 같은 &lt;b&gt;Queue&lt;/b&gt; 구현체는 &lt;b&gt;Collection 인터페이스&lt;/b&gt;를 상속하므로, 이를 &lt;b&gt;ArrayList&lt;/b&gt; 같은 &lt;b&gt;리스트로 변환 가능&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1732864537670&quot; class=&quot;java&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;public static boolean cntPlus(int num){
    boolean isCntChanged = false;
    List&amp;lt;Person&amp;gt; tmpList = new ArrayList&amp;lt;&amp;gt;(pq);
    pq.clear();
    for(Person person : tmpList){
        if(person.num == num){
            person.cnt +=1;
            isCntChanged = true;
        }
        pq.offer(person);
    }
    return isCntChanged;
}

public static void timePlus(){
    List&amp;lt;Person&amp;gt; tmpList = new ArrayList&amp;lt;&amp;gt;(pq);
    pq.clear();
    for(Person person : tmpList){
        person.time += 1;
        pq.offer(person);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt; &lt;span&gt; 정답 코드&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1732864734436&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.*;
import java.io.*;

public class Main{

    static PriorityQueue&amp;lt;Person&amp;gt; pq = new PriorityQueue&amp;lt;&amp;gt;((o1,o2) -&amp;gt; {
        if(o1.cnt != o2.cnt){
            return o1.cnt - o2.cnt; //추천횟수는 적을수록 삭제가능성 up
        } else { 
            return o2.time - o1.time; //시간은 오래될수록(클수록) 삭제가능성 up
        }
    });

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        int n = Integer.parseInt(br.readLine());
        int times = Integer.parseInt(br.readLine());

        st = new StringTokenizer(br.readLine());
        for(int i = 0; i&amp;lt;times; i++){
            int person = Integer.parseInt(st.nextToken());
            if(!cntPlus(person)) {
			            //number가 같은지 확인함 (같다면 시간만 +1, 다르다면 pq 크기에 따라 다르게)
                 if(pq.size() == n){
                     pq.poll();  
                 } 
                 pq.offer(new Person(person, 1, 0));
            }
            timePlus();
        }


        List&amp;lt;Person&amp;gt; list = new ArrayList&amp;lt;&amp;gt;(pq);

        Collections.sort(list, (o1, o2) -&amp;gt; o1.num - o2.num); //num 기준 오름차순으로 수행

        for(Person p : list){
            System.out.print(p.num + &quot; &quot;);
        }
    }

    public static boolean cntPlus(int num){
        boolean isCntChanged = false;
        List&amp;lt;Person&amp;gt; tmpList = new ArrayList&amp;lt;&amp;gt;(pq);
        pq.clear();
        for(Person person : tmpList){
            if(person.num == num){
                person.cnt +=1;
                isCntChanged = true;
            }
            pq.offer(person);
        }
        return isCntChanged;
    }

    public static void timePlus(){
        List&amp;lt;Person&amp;gt; tmpList = new ArrayList&amp;lt;&amp;gt;(pq);
        pq.clear();
        for(Person person : tmpList){
            person.time += 1;
            pq.offer(person);
        }
    }
}

class Person  {
    int num;
    int cnt;
    int time;

    public Person(int num, int cnt, int time){
        this.num = num;
        this.cnt = cnt;
        this.time = time;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;Silver1문제인데,, 생각보다 어렵게 푼 듯하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;다른 분들 풀이 참고했을때는 LinkedHashMap으로 푸셨는데, 이부분도 추후 참고해서 다시 풀어봐야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;또한, Queue를 바로 List로 변경할 수 있는지 알게되서 시간초과를 해결할 수 있었다. 앞으로도 차근차근 배워야지 !  &lt;/p&gt;</description>
      <category>알고리즘/백준</category>
      <category>1713</category>
      <category>PriorityQueue</category>
      <category>백준</category>
      <category>시뮬레이션</category>
      <category>우선순위큐</category>
      <category>후보추천하기</category>
      <author>이-프</author>
      <guid isPermaLink="true">https://for-if.tistory.com/109</guid>
      <comments>https://for-if.tistory.com/109#entry109comment</comments>
      <pubDate>Fri, 29 Nov 2024 16:21:24 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스][JAVA] 신규아이디 추천 - 문자열</title>
      <link>https://for-if.tistory.com/108</link>
      <description>&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;  문제&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;프로그래머스 | 신규아이디 추천 | level1 | 문자열&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/72410&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/72410&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1732858950854&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/72410&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ckS8wr/hyXDcvybnj/HZFWUxVYPlwpsDITjTLPrk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/cfHuG7/hyXDjOXCSb/NXVRlrTcpK8kPDVcokjaSK/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/72410&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/72410&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ckS8wr/hyXDcvybnj/HZFWUxVYPlwpsDITjTLPrk/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960,https://scrap.kakaocdn.net/dn/cfHuG7/hyXDjOXCSb/NXVRlrTcpK8kPDVcokjaSK/img.png?width=1920&amp;amp;height=960&amp;amp;face=0_0_1920_960');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt; &amp;nbsp;문제 탐색하기&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;규칙에 맞지 않는 아이디 입력시, 규칙에 맞는 아이디를 추천&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3~15 자 아이디&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;소문자, 숫자, - , _, . 만 사용 가능&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;.는 처음과 끝에 사용 x&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;연속 x (.. x)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt; &amp;nbsp;코드 설계하기&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt; 단계별로 수행하기!&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Key Point는 최대한 깔끔하게 코드 설계해서 문자열 정리하는 것&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt; &amp;nbsp;시도 회차 진행 방향&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1회차&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3단계, 4단계, 6단계에서 틀림&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3단계 | ..이 2개 이상 나타날 때니까, 2개만 나타나도 해당 (.indexOf())&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;4단계 | 맨 앞에 . 이나, 맨 뒤의 .이나 둘 다 똑같이 if문으로 진행해야함(if else로 진행 xxx)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;6단계 | str.substring(a,b) = a이상, b미만&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2회차 (정답)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1732859057684&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.*;
import java.io.*;

class Solution {
    public String solution(String new_id) {
        String answer = &quot;&quot;;
        
        //1단계 : new_id의 모든 대문자를 대응되는 소문자로 치환
        new_id = new_id.toLowerCase();
        
        //2단계 : new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다.
        for (int i = 0; i &amp;lt; new_id.length(); i++) {
            char ch = new_id.charAt(i);
            if (Character.isAlphabetic(ch) || 
                Character.isDigit(ch) || 
                ch == '-' || ch == '_' || ch == '.')
                answer += ch;
        }
        
        //3단계 : new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.
        while (answer.indexOf(&quot;..&quot;) != -1)
            answer = answer.replace(&quot;..&quot;, &quot;.&quot;);
        
        //4단계 : new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.
        if(!answer.isEmpty() &amp;amp;&amp;amp; answer.charAt(0) == '.'){
            answer = answer.substring(1);
        } 
        if (!answer.isEmpty() &amp;amp;&amp;amp; answer.charAt(answer.length()-1) == '.'){
            answer = answer.substring(0, answer.length()-1);
        }
        
        
        
        //5단계 : new_id가 빈 문자열이라면, new_id에 &quot;a&quot;를 대입합니다.
        if(answer.isEmpty()){
            answer += &quot;a&quot;;
        }
        
        //6단계 : new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다.
                 //만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.

        if(answer.length() &amp;gt; 15){
            answer = answer.substring(0, 15);
            if(answer.charAt(answer.length()-1) == '.'){
                answer = answer.substring(0, answer.length()-1);
            }
        }
        
        
        //7단계 : new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.         
        while(answer.length() &amp;lt; 3){
            char last = answer.charAt(answer.length()-1);
            answer += String.valueOf(last);
        }

        return answer;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;  문자열 문제에서 암기하면 좋을 메소드 정리&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1732859811195&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(1) 소문자 &amp;lt;-&amp;gt; 대문자
String tmp = &quot;apPLe&quot;;
tmp.toUpperCase //APPLE
tmp.toLowerCase //apple


(2) .indexOf() 
특정 '문자'나, '문자열'이 앞에서부터 처음 발견되는 인덱스를 반환
만약, 찾지 못한다면 '-1' 반환
String tmp = &quot;apPLe&quot;;
tmp.indexOf(&quot;a&quot;) //0
tmp.indexOf(&quot;pP&quot;) //1
tmp.indexOf(&quot;A&quot;) //-1


(3) .substring(int startIdx) .substring(int startIdx, int endIdx)
startIdx 이상 또는 startIdx 이상 endIdx 미만으로 특정 부분을 잘라냄
String tmp = &quot;apPLe&quot;;
tmp.substring(2) // PLe
tmp.substring(1,3) //pP

(4) .isEmpty()
문자열이 빈 문자열일 경우에 true를 반환하는 함수
tmp = &quot;&quot;;
tmp.isEmpty() //true
tmp2 = &quot;apple&quot;
tmp.isEmpty() //false


(5) .replace(CharSequence target, CharSequence replacement)
target부분을 replacement로 대치
String tmp = &quot;apppple&quot;
tmp.replace(&quot;pppp&quot;, &quot;PP&quot;) //aPPle
-&amp;gt; 만약에 tmp.replace(&quot;pp&quot;, &quot;PP&quot;) 로 하면, aPPpple가 된다 (replace는 첫 번째 매칭만!)
-&amp;gt; 그러므로, 만약 pppp를 다 바꾸고 싶으면 tmp.replaceAll(&quot;pp&quot;, &quot;PP&quot;); replaceAll로 해야함 (aPPPPPPPPle)&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;코테를 보다보면, 문자열 문제가 빈번하게 출제되는데 쉬운것 같으면서도 메소드에 대한 지식에 없으면 풀기가 난처하다 ㅠㅠ&amp;nbsp;&lt;br /&gt;쉬운 부분도 결코 놓치지 않고.. 꼭 맞아서 합격까지 !!!  ⭐⭐⭐⭐⭐&lt;/p&gt;</description>
      <category>알고리즘/프로그래머스</category>
      <category>Kakao</category>
      <category>메소드</category>
      <category>문자열</category>
      <category>신규 아이디 추천</category>
      <category>프로그래머스</category>
      <author>이-프</author>
      <guid isPermaLink="true">https://for-if.tistory.com/108</guid>
      <comments>https://for-if.tistory.com/108#entry108comment</comments>
      <pubDate>Fri, 29 Nov 2024 14:58:14 +0900</pubDate>
    </item>
    <item>
      <title>[백준][JAVA] 2631 - 줄세우기 - DP, 이진탐색</title>
      <link>https://for-if.tistory.com/107</link>
      <description>&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;  문제&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;백준 | 줄세우기 | GOLD 4 | DP, 이진탐&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2631&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/2631&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt; &amp;nbsp;문제 탐색하기&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일반적인 정렬 알고리즘은 최대 O(NlogN) ~ O(N^2) 까지 될 수 있어서&amp;hellip; 비추하는 방법일 것 같은데&lt;/li&gt;
&lt;li&gt;문제에서 N이 고작 200이하의 정수라고 주어졌고&lt;/li&gt;
&lt;li&gt;시간제한이 1초라면, 최대 40000 즉, 1초도 안넘을 것임 &amp;rArr; 그러므로 일반 정렬 사용해도 괜찮다.&lt;/li&gt;
&lt;li&gt;근데 문제는,,, &amp;lsquo;정렬&amp;rsquo;을 하는 것이 아니라, &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;lsquo;최소 몇 번으로 이동 가능&amp;rsquo;이므로 &amp;lsquo;DP&amp;rsquo;로 풀어야할 것.&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;3 7 5 2 6 1 4 - 3 5 6&lt;/li&gt;
&lt;li&gt;3 7 4 5 2 6 1 (4번 이동) - 3456&lt;/li&gt;
&lt;li&gt;3 4 5 2 6 1 7 (7번 이동) - 34567&lt;/li&gt;
&lt;li&gt;1 3 4 5 2 6 7 (1번 이동) - 1 3 4 5 6 7&lt;/li&gt;
&lt;li&gt;1 2 3 4 5 6 7 (2번 이동) - 1234567&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rArr; 지금 문제를 보면, 총 4번의 이동에서 LIS (최장 증가 부분수열) 법칙이 쓰였음을 알 수 있음&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;  알고리즘&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;LIS&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1️⃣ DP 활용 (O(n^2))&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;ARR[] = 3 7 5 2 6 1 4&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;DP = [1,1,1,1,1,1,1] : 최소 1개는 존재 (자기자신)&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;DP[1] =3&amp;lt; 7 : DP[1] = DP[1] + 1 = 2;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;DP[2] = 3 &amp;lt; 5 , 7 &amp;lt; 5(X) = DP[2] + 1 = 2;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;DP[3] = 아무것도 X = DP[3] = 1;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;DP[4] = 3 &amp;lt; 6, 5 &amp;lt; 6, 2 &amp;lt; 6 = DP[4] + 3 = 4;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;rArr; 여기서 이렇게 생각했는데 이러면 3, 5 2 이런식으로 되서 안됨 !!! 그래서 Math.max로 되는걸 확인해줘야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;⭐그렇다면 ?&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;i = 4 (arr[4] = 6)&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp; - j = 0: arr[0] &amp;lt; arr[4] (3 &amp;lt; 6) &amp;rarr; dp[4] = dp[0] + 1 = 2&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp; -&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; j = 1: arr[1] &amp;gt; arr[4] (7 &amp;gt; 6) &amp;rarr; 갱신 X &amp;rArr; dp[i] &amp;lt; dp[j] + 1&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp; -&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; j = 2: arr[2] &amp;lt; arr[4] (5 &amp;lt; 6) &amp;rarr; dp[4] = dp[2] + 1 = 3&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp; -&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; j = 3: arr[3] &amp;lt; arr[4] (2 &amp;lt; 6) &amp;rarr; dp[4] = dp[3] + 1 = 2 (이미 3이므로 갱신 X)&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;이 방식대로 계속 이어나가면 됨!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2️⃣ 이진 탐색 활용 (Binary Search) (O(nlogn))&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;수열의 크기가 크게 주어진다면, 시간 초과가 발생할 수 있으므로 효율성을 올리기 위해서는 &amp;lsquo;이진탐색&amp;rsquo;으로 최적화 작업을 이뤄 시간복잡도를 줄인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;근데,,, 이진탐색은 공식이 &amp;lsquo;오름차순 정렬&amp;rsquo;이 되어있는 수열에서 가능한데 어떻게 구현할까 ?&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;rArr; LIS의 형태를 유지하기 위해서 주어진 배열의 인덱스를 하나씩 살피며 숫자가 들어갈 위치를 이분탐색으로 탐색 !!&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;rArr; 단, 이진 탐색을 활용한 LIS는 &amp;lsquo;길이&amp;rsquo;에만 집중을 하는 것 (NOT 실제 답)&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;example&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;(1) LIS의 마지막 요소 &amp;lt; ARR[i] : LIS의 마지막에 부착&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;(2) LIS의 마지막 요소 &amp;gt; ARR[i] : 이분탐색을 활용해서 해당 요소가 어디 들어갈지 확인 &amp;amp; 대체&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;ARR[] = 3 7 5 2 6 1 4&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;LIS[] = 3&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;LIS[] = 3 7 &amp;rarr; (1)&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;LIS[] = 3 5 (2) 이분탐색을 통해 해당 INDEX에 대체함&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;LIS[] = 2 5 (2)&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;LIS[] = 2 5 6 (1)&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;rArr; 즉, 길이가 3인 LIS가 나올 것&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt; &amp;nbsp;코드 설계하기&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;아이들의 수 N, 1~n명의 줄 숫자 입력&lt;/li&gt;
&lt;li&gt;LIS 코드 작성&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;  정답 코드&lt;/h4&gt;
&lt;pre id=&quot;code_1732778046030&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;##dp##
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main{

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        int n = Integer.parseInt(br.readLine());
        int[] children = new int[n];
        int[] dp = new int[n];
        Arrays.fill(dp, 1);
        for (int i = 0; i &amp;lt; n; i++) {
            children[i] = Integer.parseInt(br.readLine());
        }

        int maximum = 0;
        for (int i = 0; i &amp;lt; n; i++) {
            for (int j = 0; j &amp;lt; i; j++) {
                if (children[i] &amp;gt; children[j] &amp;amp;&amp;amp; dp[i] &amp;lt; dp[j] + 1) {
                    dp[i] = dp[j] + 1;
                }
            }
            maximum = Math.max(maximum, dp[i]);
        }

        System.out.println(n - maximum);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1732778057489&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;## 이진탐색 ##
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class q2631_gold4_2 {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int n = Integer.parseInt(br.readLine());
        int[] arr = new int[n];
        int[] lis = new int[n];
        for (int i = 0; i &amp;lt; n; i++) {
            arr[i] = Integer.parseInt(br.readLine());
        }

        int idx = 0;
        lis[idx++] = arr[0];

        for (int i = 1; i &amp;lt; n; i++) {
            if (lis[idx - 1] &amp;lt; arr[i]) {
                lis[idx++] = arr[i];
            } else {
                int start = 0;
                int end = idx - 1;

                while (start &amp;lt;= end) {
                    int mid = start + (end - start) / 2;
                    if (lis[mid] &amp;lt; arr[i]) {
                        start = mid + 1;
                    } else {
                        end = mid - 1;
                    }
                }

                lis[start] = arr[i];
            }
        }

        int cnt = 0;
        for (int i = 0; i &amp;lt; n; i++) {
            if (lis[i] &amp;gt; 0) {
                cnt++;
            }
        }

        System.out.println(n - cnt);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;817&quot; data-origin-height=&quot;194&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBhCjA/btsKZQSFnCj/vws0fSW3y3qjB7cSx2dmMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBhCjA/btsKZQSFnCj/vws0fSW3y3qjB7cSx2dmMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBhCjA/btsKZQSFnCj/vws0fSW3y3qjB7cSx2dmMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBhCjA%2FbtsKZQSFnCj%2Fvws0fSW3y3qjB7cSx2dmMk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;817&quot; height=&quot;194&quot; data-origin-width=&quot;817&quot; data-origin-height=&quot;194&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;실제로 코드 길이 대비 확실히 이진탐색이 더 메모리가 적게 들어가긴 했다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;근데 문제의 N크기가 그렇게 큰편이 아니라 그런지 차이가 미미한듯 하다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;그럼에도 불구하고, 각 알고리즘의 시간복잡도에 따른 구현의 차이를 배운 것 같아 다행이다  &lt;/p&gt;</description>
      <category>알고리즘/백준</category>
      <category>2631</category>
      <category>DP</category>
      <category>골드</category>
      <category>백준</category>
      <category>이분탐색</category>
      <category>이진탐색</category>
      <category>줄세우기</category>
      <author>이-프</author>
      <guid isPermaLink="true">https://for-if.tistory.com/107</guid>
      <comments>https://for-if.tistory.com/107#entry107comment</comments>
      <pubDate>Thu, 28 Nov 2024 16:17:17 +0900</pubDate>
    </item>
  </channel>
</rss>