Plite
전자오락 공방
Plite
전체 방문자
오늘
어제
  • 분류 전체보기 (274)
    • 프로젝트 (18)
      • 완성 프로젝트 (3)
      • 프로젝트 진행 내역 (15)
    • 공부 및 정리 (241)
      • 백준 코드 (222)
      • C++ (8)
      • DirectX (2)
      • Unreal Engine (6)
      • 프로그래밍 패턴 (3)
    • 기타 (12)
      • 기타 주저리 (10)
    • 게임과 취미 (1)
    • 대문 (1)

블로그 메뉴

  • 홈
  • 프로젝트
  • 취미, 일상
  • 백준 프로필

공지사항

  • [Read Me]
  • 제 블로그에 방문하신 것을 환영합니다.

인기 글

태그

  • 위상 정렬
  • 정수론
  • 백준
  • 문자열
  • 조합론
  • 이분탐색
  • 유니온 파인드
  • 트라이
  • KMP
  • C++
  • UC++
  • 동적계획법
  • 세그먼트 트리
  • 브루트포스
  • SCC
  • 큐
  • 우선순위큐
  • 백트래킹
  • 정렬
  • LCA
  • 구현
  • 누적합
  • 스택
  • 수학
  • 그래프
  • 기하
  • 분할정복
  • 트리
  • 최소 스패닝 트리
  • 투포인터

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Plite

전자오락 공방

[C++]백준 - 1450번 문제
공부 및 정리/백준 코드

[C++]백준 - 1450번 문제

2021. 9. 22. 16:40

1450번: 냅색문제 (acmicpc.net)

 

1450번: 냅색문제

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

www.acmicpc.net

 

1450번 : 냅색문제


세준이는 N개의 물건을 가지고 있고, 최대 C만큼의 무게를 넣을 수 있는 가방을 하나 가지고 있다.

N개의 물건을 가방에 넣는 방법의 수를 구하는 프로그램을 작성하시오.

 

입력


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

 

 

출력


첫째 줄에 가방에 넣는 방법의 수를 출력한다.

 

 


 

생각해 볼 점


벡터를 2개를 쓸 것입니다.

 

우선, 입력을 받기 전에 벡터 2개에 0을 집어넣습니다. 아무것도 안넣는 것 역시 한가지 방법이기 때문입니다.

 

입력을 2등분하여, 두 벡터에 넣습니다.

 

vector1은 0부터 2 / N까지

vector2는 2 / N부터 N까지 받습니다.

 

입력을 추가할 때마다, C를 넘지 않는 무게조합을 더하여 추가합니다.

 

예를들어, 벡터 1이 {1, 2, 4} 순서대로 입력을 받는다고 하면

 

1이 입력되기 전 : {0}

1이 입력됨 : {0, 0 + 1}

2가 입력됨 : {0, 1, 2, 1 + 2}

3이 입력됨 : {0, 1, 2, 3, 4, 1 + 4, 2+ 4, 3 + 4}

 

결과 : {0, 1, 2, 3, 4, 5, 6, 7}

 

위 벡터는 1, 2, 4의 아이템으로 만들 수 있는 모든 무게의 조합입니다.

 

벡터 2 역시 위와 동일하게 만들어 줍니다.

 

그 후, 벡터 1과 벡터 2의 아이템을 모두 조합하여 가능한 모든 경우의 수를 구할 것입니다.

 

이 때, 벡터 1과 벡터 2중 한 쪽을 정렬하면, 무게 C가 넘어가는 순간 더 비교를 하지 않아도 됩니다.

 

V2는 정렬되어있으므로 V1과 V2를 더해가던 중, C를 넘는 조합이 발견되면 break가 가능 

 

C를 넘지 않는 모든 케이스를 구하여 갯수를 출력하면 됩니다.

 

코드


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() 
{
	int N, C;
	scanf("%d %d", &N, &C);
	
	vector<int> items1;
	vector<int> items2;
	items1.push_back(0);
	items2.push_back(0);
    
    //입력을 이등분하여 받음
	for(int i = 0; i < N / 2; i++)
	{
	    int input;
	    scanf("%d", &input);
	    
	    int s = items1.size();
        
        //새 물건이 추가될 때마다 가능한 모든 조합을 추가함
	    for(int i = 0; i < s; i++)
	    {
	        if(items1[i] + input <= C) items1.push_back(items1[i] + input);
	    }
	}
	
	//1번 경우와 동일하게 진행
	for(int i = N / 2; i < N; i++)
	{
	    int input;
	    scanf("%d", &input);
	    
	    int s = items2.size();
	    for(int i = 0; i < s; i++)
	    {
	        if(items2[i] + input <= C) items2.push_back(items2[i] + input);
	    }
	}
    
    //한쪽만 정렬
	sort(items2.begin(), items2.end());
	
	int result = 0;
	
    
    //1번 벡터와 2번 벡터의 경우의 수를 조합
	for(int item1 : items1)
	{
	    for(int item2 : items2)
	    {
        	//2번 벡터는 정렬되었으므로, 무게가 C를 넘어가는 순간 break
	        if(item1 + item2 <= C) result++;
	        else break;
	    }
	}
	printf("%d", result);
	
	return 0;
}

 

그 외


솔직히 어떻게 풀지 감도 못잡고 있었는데.. 검색해보니 이런 방법으로 풀 수 있을 줄은 몰랐습니다.

저작자표시 (새창열림)

'공부 및 정리 > 백준 코드' 카테고리의 다른 글

[C++]백준 - 2263번 문제  (0) 2021.09.24
[C++]백준 - 14002번 문제  (0) 2021.09.22
[C++]백준 - 1991번 문제  (0) 2021.09.20
[C++]백준 - 1967번 문제  (0) 2021.09.20
[C++]백준 - 1167번 문제  (0) 2021.09.18
    '공부 및 정리/백준 코드' 카테고리의 다른 글
    • [C++]백준 - 2263번 문제
    • [C++]백준 - 14002번 문제
    • [C++]백준 - 1991번 문제
    • [C++]백준 - 1967번 문제
    Plite
    Plite
    개발 일지, 게임 이야기 등을 적어두는 공간입니다.

    티스토리툴바