Compy's Blog
261 words
1 minutes
[BOJ] 부분수열의 합 2
2025-03-20

부분수열의 합 2

TimeLimitMemoryLimitConditionTAG
1s256MB(1 ≤ N ≤ 40, 1 <= |S| <= 1,000,000)BinarySearch

이거는 아이디어가 중요한데.. 그냥 반반 쪼개서 2^20 * 2로 만들어서 생각하면 됩니다

정답 코드
#include <iostream>
#include <queue>
#include <algorithm>
#include<set>
#include <map>
using namespace std;
using ll = long long;

int inf = 1e9;
int nums[41];

vector<ll> A, B;

void getSum(int current, int end, int current_sum, vector<ll>& container){
    container.push_back(current_sum);
    for(int i = current+1; i < end; i++)
        getSum(i, end, current_sum+nums[i], container);
    
}




void solution(){
    int n, s;
    cin >> n >> s;
    
    ll result = 0;
    
    for(int i = 0; i < n; i++) cin >> nums[i];
    
    
    if(n == 1){
        cout << (s == nums[0]);
        return;
    }
    
    
    getSum(0, n/2, 0, A);
    getSum(0, n/2, nums[0], A);
    getSum(n/2, n, 0, B);
    getSum(n/2, n, nums[n/2], B);

    
    sort(A.begin(), A.end());
    A.erase(--upper_bound(A.begin(), A.end(), 0));
//    cout << A.size() << " " << B.size() << "\n";
    
    
    
    
    for(int i = 0; i < B.size(); i++){
        ll current = B[i];
        if(B[i] == s) result++;
        if(*lower_bound(A.begin(), A.end(), s - current) + current != s) continue;
        
        ll idx = upper_bound(A.begin(), A.end(), s - current) - A.begin();
        idx -= lower_bound(A.begin(), A.end(), s - current) - A.begin();
        
        result += idx;
    }
    
    
    cout << result - (s == 0);
    
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    solution();
    return 0;
}



// -3 -2 -1 -3 -4 -5 -6 0
// 0 1 2 3 5 4 3 3 2 1 6 6
[BOJ] 부분수열의 합 2
https://compy07.github.io/Blog/posts/boj/1208/
Author
뒹굴뒹굴 이정훈 공부방
Published at
2025-03-20