[백준] 1480 보석모으기 - Java

2022. 7. 24. 03:21· Algorithm/백준 문제풀이
목차
  1. 문제출저
  2. 문제풀이 
  3. 소스코드
  4. 참조

 

 

문제출저

https://www.acmicpc.net/problem/1480

 

1480번: 보석 모으기

첫째 줄에 보석의 개수 N, 가방의 개수 M, 가방의 최대 한도 C가 주어진다. N은 1보다 크거나 같고, 13보다 작거나 같은 자연수이고, M은 1보다 크거나 같고, 10보다 작거나 같은 자연수이다. C는 1보

www.acmicpc.net

 

 

 

문제풀이 

주어진 가방을 이용해 최대한 많은 보석을 담는 방법을 구하는 문제이다.

이를 위해 중복을 줄여주는 비트마스크와 다이나믹프로그래밍, 완전탐색을 위한 DFS를 활용한다.

 

 

int MAX = 14;
dp = new int[1 << MAX][11][21];

1 << MAX : 

A << B의 의미는 정수 A을 왼쪽으로 B만큼 이동한다는 뜻 이다.

알고리즘적으로 MAX의 수 14만큼 비트들을 만들라는 뜻으로 받아들였다.

 

예) 1 << 5 이면 visited = new boolean[5]; 라 이해함.

 

 

if(path & (1 << i)) > 0 ) continue;

path & (1 << i) 

& 는 and 연산자로 A & B 인 경우 A,B 중 하나라도 0이 있으면 0이 나온다. 즉 1이 나올려면 A와 B가 모두 1이어야 한다. 

path & (1 << i) 가 1이 나오기 위해서는 path 와 (1 << i)가 일치해야 한다.

즉 저 조건문은 보석들을 담은 경우의 수가 같으면 넘어간다는 의미이다.

 

예) 1 -> 2 -> 4 순서로 보석을 담으면 비트마스크는 1011, 2 -> 1 -> 4 순서로 보석을 담아도 비트마스크는 1011이다. 이러한 중복을 방지해준다.

 

 

 if(cap >= board[i])
{
    dp[path][idx][cap] = Math.max(dp[path][idx][cap], dfs(path | (1 << i), idx, cap - board[i]) + 1);
}

위의 조건문은 남은 가방 용량이 다음에 탐색한 보석의 무게보다 크거나 같으면 담는다는 의미이다.

이 때 | 비트 연산자가 사용된다.

| 비트는 A | B 중 A,B 둘 중 하나가 1이면 1이 나온다.

path | (1 << i) 의 의미는 path에 i를 추가해 경로를 확장한다는 의미이다.

 

 

 

 

 

소스코드

package studyGroup.july.july23;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

/*

bitmast + dp

 */


public class 백준1480보석모으기 {

    static int MAX = 14; // 보석의 개수 n은  13보다 작거나 같다.
    static int n, m, c;
    static int[] board;
    static int[][][] dp;


    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        n = Integer.parseInt(st.nextToken()); // 보석의 개수
        m = Integer.parseInt(st.nextToken()); // 가방의 개수
        c = Integer.parseInt(st.nextToken()); // 가방의 최대 한도

        board = new int[n];

        // 1 << max : max개의 비트를 생성한다. <<은 정수1을 왼쪽으로 14만큼 이동이라는 뜻 이다.
        // 보석의 크기는 13보다 작다 -> 1 << max
        // 보석의 크기는 10보다 작다. -> 11
        // 가방의 최대한도는 20보다 작다 -> 21
        dp = new int[1 << MAX][11][21];

        st = new StringTokenizer(br.readLine());
        for(int i = 0; i < n; i++)
        {
            board[i] = Integer.parseInt(st.nextToken());
        }

        int answer = dfs(0,0,c);
        System.out.println(answer);


    }

    // path : 탐색한 보석의 index
    // idx : 가방의 순서
    // k : 쓸 수 있는 가방의 용량 (남아 있는 양)
    public static int dfs(int path, int idx, int cap) {


        // 모든 보석이나, 모든 가방을 사용했다면 return
        if(( (path == (1<<n)-1) || idx == m ))
        {
            return 0;
        }


        // 이미 방문한 곳이면
        if(dp[path][idx][cap] != 0) {
            return dp[path][idx][cap];
        }

        for(int i = 0; i < n; i++)
        {
            // 이미 사용된 보석이면 넘어감
            if( (path & (1 << i)) > 0)
            {
                continue;
            }


            // 가방에 담을 수 있다면 가방에 담고 계속 탐색
            if(cap >= board[i])
            {
                dp[path][idx][cap] = Math.max(dp[path][idx][cap], dfs(path | (1 << i), idx, cap - board[i]) + 1);
            }
            // 가방에 담을 수 없다면 다음 가방을 선택하고 탐색 
            else
            {
                // 용량이 조금 남았더라도, 다음 가방(idx + 1) 탐색
                dp[path][idx][cap] = Math.max(dp[path][idx][cap], dfs(path, idx+1, c));
            }


        }


        return dp[path][idx][cap];

    }

}

 

 

 

참조

https://coder-in-war.tistory.com/entry/BOJ-JAVA1480-%EB%B3%B4%EC%84%9D%EB%AA%A8%EC%9C%BC%EA%B8%B0

 

[ BOJ ][JAVA][1480] 보석모으기

https://www.acmicpc.net/problem/1480 1480번: 보석 모으기 첫째 줄에 보석의 개수 N, 가방의 개수 M, 가방의 최대 한도 C가 주어진다. N은 1보다 크거나 같고, 13보다 작거나 같은 자연수이고, M은 1보다 크거나

coder-in-war.tistory.com

 

 

감사합니다.

  1. 문제출저
  2. 문제풀이 
  3. 소스코드
  4. 참조
'Algorithm/백준 문제풀이' 카테고리의 다른 글
  • [백준] 20055 컨베이어 벨트 위의 로봇 - Java
  • [백준] 2098 외판원 순회 - Java
  • [백준] 16929번 Two Dots - Java
  • [프로그래머스] 아이템 줍기 - Java
너지살
너지살
너지살
너지살개발자
너지살
전체
오늘
어제
  • 분류 전체보기 (375)
    • 잡식 (2)
      • 티스토리 (2)
    • 개발 일지 (0)
      • OMS 프로젝트 (4)
      • 우테코 6기 프리코스 (1)
    • Git (2)
    • JAVA (15)
      • Java 공부 (6)
      • 자료구조 (4)
      • 도움되는 메모 (4)
    • DevOps (18)
      • AWS (6)
      • Docker (2)
      • Jenkins (1)
      • Nginx (1)
      • Kafka (6)
      • RabbitMQ (2)
    • Spring, Spring Boot (16)
      • Test Code (1)
      • AOP (2)
      • Batch (3)
      • Cache - Redis (5)
      • Cloud Config - 설정 파일 관리 (3)
      • 성능 측정 (1)
      • 예외 처리 (1)
    • BackEnd (1)
      • Spring 공부 (1)
      • Thymeleaft (0)
    • DB (17)
      • JPA (2)
      • DB 공부 (3)
      • DB 포스팅 (4)
      • DB 답장 (1)
      • MySQL (2)
      • Redis (5)
      • MongoDB (0)
    • CS (8)
      • Spring (4)
      • DataBase (3)
      • Java (1)
    • Algorithm (203)
      • 알고리즘 개념 (5)
      • 정렬 알고리즘 (11)
      • 프로그래머스 문제풀이 (18)
      • 백준 문제풀이 (165)
      • 소프티어 문제풀이 (3)
      • 알고리즘 시험 정리 (1)
    • SQL (0)
      • 문법 (1)
      • 프로그래머스 문제풀이 (52)
      • 리트코드 문제풀이 (19)
    • IT (1)
      • IT 공부 (1)
    • 정리 (10)
      • 질문 정리 (10)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 다이나믹프로그래밍
  • DFS
  • 최소 신장 트리
  • db
  • Java
  • 두 포인터
  • Spring Boot Redis 연결
  • two pointer
  • Java 정리
  • 크루스칼 알고리즘
  • Union-Find
  • 부분탐색
  • Next permutation
  • docker
  • 자료구조
  • 소프티어
  • Sorting algorithm
  • 알고리즘
  • 그래프 이론
  • Algorithm
  • git
  • 투포인트
  • JPA
  • 백준
  • 외판원 순회 문제
  • redis
  • 질문 정리
  • 경로표현식
  • 분리 집합
  • 깊이/너비 우선탐색
  • 그래프 탐색
  • dynamic programing
  • DP
  • Bitmast
  • 유니온파인드
  • Spring Batch
  • MST
  • cache
  • 우선수위큐
  • 병렬 처리
  • Spring Boot
  • 투 포인터
  • dynamiceprogramming
  • 데이터베이스
  • 최소 스패닝 트리
  • 비트마스킹
  • Test code
  • 설정
  • 다이나믹 프로그래밍
  • 다음 순열 찾기

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
너지살
[백준] 1480 보석모으기 - Java
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.