길민호(ethan.mino)
코딩수첩
길민호(ethan.mino)
전체 방문자
오늘
어제
  • 분류 전체보기 (215)
    • Computer Science (0)
    • Web (6)
      • CSS (0)
      • HTML (0)
    • Node.js (0)
    • Javascript (2)
    • Java (46)
      • Spring (27)
      • Jsp (0)
    • C\C++ (2)
    • Programming (0)
    • AI (0)
    • Database (7)
    • Git (5)
    • Algorithm (119)
      • Stack (0)
      • Queue (0)
      • Linked List (0)
      • Sort (0)
      • Simulation (27)
      • Recursion (0)
      • Backtracking (4)
      • Two Pointer (3)
      • Dynamic Programming (19)
      • Greedy (10)
      • Graph (3)
      • Dijkstra (1)
      • BFS\DFS (8)
      • Floyd (1)
      • MST (4)
      • Tree (4)
      • Binary Search (8)
      • Binary Search Tree (4)
    • IntelliJ (4)
    • Vscode (0)
    • Operating System (0)
    • 후기 (3)
    • 성장일지 (13)
    • 스터디 (7)
    • 설치 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • ㅡ

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
길민호(ethan.mino)

코딩수첩

Algorithm

[백준 1182번] 부분수열의 합 (C/C++)

2022. 3. 9. 17:08

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

 

1182번: 부분수열의 합

첫째 줄에 정수의 개수를 나타내는 N과 정수 S가 주어진다. (1 ≤ N ≤ 20, |S| ≤ 1,000,000) 둘째 줄에 N개의 정수가 빈 칸을 사이에 두고 주어진다. 주어지는 정수의 절댓값은 100,000을 넘지 않는다.

www.acmicpc.net


부분 수열을 선택하기 위해서 길이가 1 ~ n까지의 부분 수열을 모두 뽑았습니다.

하지만, n의 최대 값이 20이기 때문에 순서가 다른 수열까지 모두 뽑을 경우 시간초과가 발생합니다.

 

아래 풀이의 핵심은 17번째 라인입니다. i의 초기값이 r로 시작하고, 재귀 함수 호출 시 i + 1을 전달함으로써 다음 선택할 숫자를 이전에 선택한 숫자 다음 인덱스부터 확인함으로써 순서만 다른 수열은 계산에서 제외됩니다.

#include <bits/stdc++.h>
using namespace std;

int arr[21];    // 전체 수열을 저장하는 배열
bool isused[21];    // 숫자의 선택 여부를 저장하는 상태 배얄
int selected[21];   // 선택된 숫자를 저장하는 배열

int n, s, ans = 0;

void seq(int r, int m, int a){  // 길이가 a인 수열을 선택할 때, 
                                // index r 이상의 범위에서 a-m+1개의 숫자를 선택하는 함수
    if(m == a + 1){ // 수열의 길이만큼 숫자를 선택한 경우
        int sum = 0;
        for(int i = 0; i < a; i++) sum += selected[i];  // 선택된 숫자들을 모두 합함.

        if(sum == s) ans++; // 선택된 숫자들의 합이 s인 경우, 경우의 수 증가
    }else{
        for(int i = r; i < n; i++){
            if(!isused[i]){
                isused[i] = true; selected[m - 1] = arr[i];
                seq(i + 1, m + 1, a);
                isused[i] = false;
            }
        }
    }
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    
    cin >> n >> s;

    for(int i = 0; i < n; i++)  cin >> arr[i];
    
    for(int i = 1; i <= n; i++) seq(0, 1, i); // 부분수열의 길이가 1 ~ n이 되도록 함
    cout << ans;
}

아래는 사용한 테스트 케이스입니다.

5 3
3 2 3 2 5

20 5
3 2 3 2 5 6 1 2 4 5 1 2 5 6 8 2 3 5 5 1

 

'Algorithm' 카테고리의 다른 글

[백준 18809번] Gaaaaaaaaaarden (C/C++)  (0) 2022.03.11
[백준 1941번] 소문난 칠공주 (C/C++)  (0) 2022.03.11
[백준 15655번] N과 M (9) (C/C++)  (0) 2022.03.09
[백준 9663번] N-Queen (C/C++)  (0) 2022.03.08
[백준 2448번] 별 찍기 - 11 (C/C++)  (0) 2022.03.04
    'Algorithm' 카테고리의 다른 글
    • [백준 1941번] 소문난 칠공주 (C/C++)
    • [백준 15655번] N과 M (9) (C/C++)
    • [백준 9663번] N-Queen (C/C++)
    • [백준 2448번] 별 찍기 - 11 (C/C++)
    길민호(ethan.mino)
    길민호(ethan.mino)
    💻 호기심 많은 서버 개발자 길민호입니다.

    티스토리툴바