알고리즘 문제풀이/백준
[C++] 백준 2143 - 두 배열의 합
jiminai
2023. 9. 3. 22:01
반응형
<문제 링크>
https://www.acmicpc.net/problem/2143
11053번: 가장 긴 증가하는 부분 수열
수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {10, 20, 10, 30, 20, 50} 이
www.acmicpc.net
<알고리즘 분류>
- 누적 합(Cumulative Sum)
- 이분 탐색(Binary Search)
<풀이>
우선 두 배열의 크기가 모두 1000이기 때문에, O(N^2)의 이중for문을 통해 가능한 모든 부분배열의 합의 경우의 수를 Asumcase, Bsumcase에 저장하였다.
그 이후, O(logN)의 lower_bound, upper_bound를 활용하여 합을 만족하는 원소의 개수를 구하였다.
마지막에 채점을 하는데 68%에서 틀렸다고 나왔는데, 알고 보니 답이 int형 범위를 초과하는 경우를 고려하지 못했다.
ans도 long long 형으로 바꿔줘야, 정답이 된다.
<코드>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int n, m;
long long T;
int Asum[1001];
int Bsum[1001];
vector <long long> Asumcase;
vector <long long> Bsumcase;
int main(){
long long ans = 0;
cin >> T;
cin >> n;
for (int i=1; i<=n; i++){
cin >> Asum[i];
Asum[i] += Asum[i-1];
}
cin >> m;
for (int i=1; i<=m; i++){
cin >> Bsum[i];
Bsum[i] += Bsum[i-1];
}
for (int i=1; i<=n; i++){
for(int j=i; j<=n; j++){
Asumcase.push_back(Asum[j]-Asum[i-1]);
}
}
for (int i=1; i<=m; i++){
for(int j=i; j<=m; j++){
Bsumcase.push_back(Bsum[j]-Bsum[i-1]);
}
}
sort(Asumcase.begin(), Asumcase.end());
sort(Bsumcase.begin(), Bsumcase.end());
for (int i=0; i<Asumcase.size(); i++){
int low = lower_bound(Bsumcase.begin(), Bsumcase.end(), T-Asumcase[i]) - Bsumcase.begin();
int high = upper_bound(Bsumcase.begin(), Bsumcase.end(), T-Asumcase[i])- Bsumcase.begin();
ans += high - low;
}
cout << ans << "\n" ;
}
반응형