[C++] 백준 1450 - 냅색문제

2023. 8. 26. 13:56·알고리즘 문제풀이/백준
반응형

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

 

1450번: 냅색문제

첫째 줄에 N과 C가 주어진다. N은 30보다 작거나 같은 자연수, C는 109보다 작거나 같은 음이 아닌 정수이다. 둘째 줄에 물건의 무게가 주어진다. 무게도 109보다 작거나 같은 자연수이다.

www.acmicpc.net

<알고리즘 분류> 

 - 이분 탐색(Binary Search) 

 - 깊이 우선 탐색(Depth First Search) 

<풀이> 

  1. 30개의 물건이 있고, 이를 선택하는 경우의 수를 모두 더하는 최대 경우의 수는

이다. 따라서 O(2^N)의 시간복잡도를 가지므로 제한시간 1초인 문제에서 시간초과가 발생한다! 

결국 이것을 줄일 수 있는 방법은 

1. 물건들을 절반으로 분리한다.(part1 집합과 part2 집합으로 분리) 

2. 각각의 part에서 만들 수 있는 물건의 무게 값을 push_back 해준다. (이때의 최대 시간복잡도는 O(2^(N/2))이다.) 

3. part1의 집합들을 순회하며(O(N/2)), C-part1[i]를 만족하는 값을 sort된 part2 집합에서 upper_bound(이분탐색+최고인덱스 찾기 알고리즘(O(log(N/2)))을 사용한다. 

결국 이 문제의 시간복잡도는  O(2^(N/2)log2^(N/2)) = O(N*2^(N/2)) 이다. 

 

위의 설명은 다소 비약이 있으니, 예를 들어 설명해 보자. 

<코드>

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <numeric>


using namespace std;
long long N, C; // 물건개수, 최대무게
long long stuff[31];
vector <long long> part1;
vector <long long> part2;
long long cnt = 0;

void dfs(int start, int end, vector <long long>& part, long long sum){
    if(start > end){
        part.push_back(sum);
        return ;
    }
    else { //dfs 2개 : 해당 인덱스(start)를 더해, 말아? 
        dfs(start + 1, end, part, sum); 
        dfs(start + 1, end, part, sum + stuff[start]);
    }
}

int main(){
    cin.tie(NULL);
    cin >> N >> C;
    for (int i=0; i<N; i++){
        cin >> stuff[i];
    }

    dfs(0,N/2, part1, 0);
    dfs(N/2 + 1, N-1, part2, 0);
    sort(part2.begin(), part2.end());
    
    for (int i=0; i < part1.size(); i++){
        cnt += upper_bound(part2.begin(), part2.end(), C - part1[i]) - part2.begin();
    }

    cout << cnt;


}

 

반응형
저작자표시 비영리 변경금지 (새창열림)

'알고리즘 문제풀이 > 백준' 카테고리의 다른 글

[C++] 백준 1253 - 좋다  (2) 2023.08.28
[C++] 백준 2110 - 공유기 설치  (0) 2023.08.28
[C++] 백준 2565 - 전깃줄  (0) 2023.08.24
[C++] 백준 2056 - 작업  (2) 2023.08.18
[C++] 백준 1238 - 파티  (0) 2023.08.16
'알고리즘 문제풀이/백준' 카테고리의 다른 글
  • [C++] 백준 1253 - 좋다
  • [C++] 백준 2110 - 공유기 설치
  • [C++] 백준 2565 - 전깃줄
  • [C++] 백준 2056 - 작업
jiminai
jiminai
안녕하세요, 고려대학교 컴퓨터학과 학부생의 컴퓨터 공부 기록입니다👻
    반응형
  • jiminai
    컴퓨터 공부 Blog
    jiminai
  • 전체
    오늘
    어제
    • 분류 전체보기 (32)
      • AI Paper Review (9)
        • MLLMs (4)
        • Reinforcement Learning (2)
        • NLP (3)
      • 알고리즘 문제풀이 (18)
        • 백준 (17)
        • 프로그래머스 (1)
        • 알고리즘 이론 공부 (0)
      • AI 개념 정리 (2)
        • Pytorch 공부 (1)
      • Web Development (1)
      • 대외활동&프로젝트&대회 (2)
  • 블로그 메뉴

    • 홈
    • 방명록
    • 프로필
    • Github
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    두 배열의 합
    2056
    냅색문제
    이분탐색
    다이나믹프로그래밍
    개발
    dfs
    11000
    2467
    BFS
    13975
    백준
    벡준
    DP
    가장긴증가하는부분수열
    fasttext
    Dikjstra
    투포인터
    HACKUTHON 2023
    누적합
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
jiminai
[C++] 백준 1450 - 냅색문제
상단으로

티스토리툴바