레야몬
[C++] 1208번 부분수열의 합 2 - 중간에서 만나기 본문
#include <iostream>
#include <algorithm>
#include <map>
#define LOOP(i, N) for(int i=1; i<=N; i++)
#define MAX_CNT 42
using namespace std;
typedef long long int lld;
int N, S; //정수의 개수 N, 정수의 합 S
int num[MAX_CNT]; //1~N까지의 숫자
map<int, int> sub_sum; //부분수열의 합
int boun; //경계: boundary
lld cnt;
void leftSum(int left, int sum) //왼쪽 부분수열의 합
{
if(left==boun) {
sub_sum[sum]++;
return;
}
leftSum(left+1, sum);
leftSum(left+1, sum+num[left]);
}
void rightSum(int left, int sum) //오른쪽 부분수열의 합
{
if(left==N+1) {
cnt+=sub_sum[S-sum];
return;
}
rightSum(left+1, sum);
rightSum(left+1, sum+num[left]);
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> N >> S; boun=N/2;
LOOP(i, N) cin >> num[i];
if(N!=1) {
leftSum(1, 0); rightSum(boun, 0); //각 부분수열의 합 구하기
cout << (S ? cnt:cnt-1); //S가 0일경우 공집합도 있으므로 -1해서 출력
}
else
cout << (num[1]==S);
return 0;
}
처음에는 이분 탐색이 태그 되어 있길레 왼쪽 부분 수열 찾고 오른쪽 부분 수열 찾아서 정렬한 다음에 이분 탐색으로 찾아야 되는 줄 알았는데 생각해보니까 그냥 map 써서 하면 되는 거였다.
map으로 하게 되면 시간이 996?ms 정도 나와서 엄청 느리게 나오는데 그냥 배열 400000개 해서 -는 200000해서 저장하면 엄청 빠르게 시간을 줄일 수 있다. 찾아보니 이런 코드가 있어서 밑에 적었다.
<map 사용 X>
https://www.acmicpc.net/source/25030948
로그인
www.acmicpc.net
<C++ map>
https://life-with-coding.tistory.com/305
[C++][STL] map 사용법 정리
인트로 안녕하세요. 오늘은 C++ STL 연관 컨테이너 중 하나인 map에 대해 알려드리겠습니다. 목차 1) Map이란? 2) Map 기본 형태 3) Map 정렬 4) Map 사용방법 - 헤더 포함 - map 선언 - search : map에서 데이터..
life-with-coding.tistory.com
※현재 고등학교 등교중인 학생입니다. 이제 알고리즘을 본격적으로 공부하기 시작해서 아직 초보입니다. 혹시 제가 잘못 알고있는 점이나 더 좋은 풀이 방법이 있어 댓글에 남겨주시면 감사히 하나하나 열심히 읽어보겠습니다. 좋아요, 단순한 댓글 한마디라도 저에겐 큰 힘이 됩니다! 감사합니다.
'알고리즘 > 백준' 카테고리의 다른 글
[C++] 2098번 외판원 순회 - DP, 비트마스킹, 외판원 순회 (0) | 2022.09.21 |
---|---|
[C++] 1806번 부분합 - 두 포인터 (0) | 2022.09.21 |
[C++] 1202번 보석 도둑 - 그리디, 정렬, 우선순위 큐 (0) | 2022.09.20 |
[C++] 1005번 ACM Craft - DP, 위상 정렬, DFS (0) | 2022.09.20 |
[C++] 1197번 최소 스패닝 트리 - 최소 스패닝 트리, Union-Find (2) | 2022.09.07 |
Comments