-
[2568] 전깃줄 - 2BOJ 2021. 9. 2. 10:17
https://www.acmicpc.net/problem/2568
2568번: 전깃줄 - 2
첫째 줄에는 두 전봇대 사이의 전깃줄의 개수가 주어진다. 전깃줄의 개수는 100,000 이하의 자연수이다. 둘째 줄부터 한 줄에 하나씩 전깃줄이 A전봇대와 연결되는 위치의 번호와 B전봇대와 연결
www.acmicpc.net
<문제>
잘 생각해보면 아래와 같은 문제라고 할 수 있다.
-> 가장 긴 증가하는 부분수열의 최적해 + 최적해역추적
N이 10만이고, 시간제한이 1초이므로 O(NlogN)으로 구현해야 한다. 결국 아래문제와 같은 문제라는걸 알 수 있다.
https://www.acmicpc.net/problem/14003
14003번: 가장 긴 증가하는 부분 수열 5
첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (-1,000,000,000 ≤ Ai ≤ 1,000,000,000)
www.acmicpc.net
<소스코드>
1234567891011121314151617181920212223242526272829303132333435363738#include <stdio.h>#include<iostream>#include<vector>#include<algorithm>using namespace std;int n;int main() {int i, j;scanf("%d", &n);vector<pair<int, int> >v(n);for (i = 0; i < n; i++)cin >> v[i].first >> v[i].second;sort(v.begin(), v.end());vector<int> stk;vector<pair<int,int>> path;for (i = 0; i < n; i++) {if (stk.empty() || stk.back() < v[i].second) {path.push_back({ stk.size(), v[i].first });stk.push_back(v[i].second);}else {auto iter = lower_bound(stk.begin(), stk.end(), v[i].second);*iter = v[i].second;path.push_back({ iter - stk.begin(), v[i].first });}}vector<int> ans;for (i = path.size() - 1, j = stk.size() - 1; i >= 0; i--) {if (path[i].first == j) j--;else ans.push_back(path[i].second);}sort(ans.begin(), ans.end());printf("%d\n", ans.size());for (auto i : ans)printf("%d\n", i);return 0;}cs 'BOJ' 카테고리의 다른 글
[1806] 부분합 (0) 2021.09.02 [17609] 회문 (0) 2021.09.02 [1629] 곱셈 (0) 2021.09.02 [15961] 회전 초밥 (0) 2021.09.02 [9663] N-Queen (0) 2021.09.02