본문 바로가기

BOJ157

[C++] 백준 2565번 : 전깃줄 https://www.acmicpc.net/problem/2565 2565번: 전깃줄 첫째 줄에는 두 전봇대 사이의 전깃줄의 개수가 주어진다. 전깃줄의 개수는 100 이하의 자연수이다. 둘째 줄부터 한 줄에 하나씩 전깃줄이 A전봇대와 연결되는 위치의 번호와 B전봇대와 연결되는 www.acmicpc.net 문제 풀이 전깃줄이 교차하지 않으려면 선들이 평행을 이뤄야 한다. 전깃줄의 각 꼭짓점은 위에서 아래로 내림차순을 이루고 있어서 LIS를 접목시키면 쉽게 풀 수 있다. 전깃줄을 이루는 각 꼭짓점의 숫자들이 LIS를 이룬다면 교차하지 않는 전깃줄들이 최대가 된다. 한쪽이 정렬되어있을 때 반대쪽의 LIS를 따지면 해결된다. 정렬은 STL에서 제공하는 sort 함수로 정렬하고 반대쪽 전봇대(B)의 값들의 LIS.. 2021. 6. 23.
[C++] 백준 11054번 : 가장 긴 바이토닉 부분 수열 https://www.acmicpc.net/problem/11054 11054번: 가장 긴 바이토닉 부분 수열 첫째 줄에 수열 A의 크기 N이 주어지고, 둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ N ≤ 1,000, 1 ≤ Ai ≤ 1,000) www.acmicpc.net 문제 풀이 바이토닉 수열은 LIS의 변형으로 커지면서 작아지는 부분 수열이다. k번째를 기준으로 오르내림이 바뀌므로 정방향으로 LIS를 구하고 역방향으로 LIS를 구해서 DP 값을 따진다. 여기서 주의할 점은 각 DP를 더한 값 중 가장 큰 값을 -1을 해야 한다는 점인데, 이유는 중복돼서 그렇다. 예를 들면, 문제 속 수열 { 1, 5, 2, 1, 4, 3, 4, 5, 2, 1 }에서 각 LIS는 정방향 : { 1.. 2021. 6. 23.
[C++] 백준 14003번 : 가장 긴 증가하는 부분 수열5 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 문제 접근 LIS 4번 문제와 다른 점은 인풋의 갯수와 크기 뿐이다. 따라서 이전과 동일하다. 코드 #include using namespace std; int n; int arr[1000001], dp[1000001], p[1000001]; int binary(int left, int right, int key) { int mid; while (left = key).. 2021. 6. 22.
[C++] 백준 14002번 : 가장 긴 증가하는 부분 수열4 https://www.acmicpc.net/problem/14002 14002번: 가장 긴 증가하는 부분 수열 4 수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {10, 20, 10, 30, 20, 50} 이 www.acmicpc.net 문제 풀이 LIS 1번 문제에서 다음 버전으로 LIS의 길이와 LIS 자체를 출력해야한다. 배열 L은 LIS의 길이를 구하기 위한 배열이고 배열 P는 arr의 원소들의 lower_bound를 저장하는 배열이다. 함수 Backtrace는 배열 P에 저장된 lower_bound로 LIS를 출력하는 재귀함수이다. P[i].. 2021. 6. 22.
[C++] 백준 12738번 : 가장 긴 증가하는 부분 수열3 https://www.acmicpc.net/problem/12738 12738번: 가장 긴 증가하는 부분 수열 3 첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (-1,000,000,000 ≤ Ai ≤ 1,000,000,000) www.acmicpc.net 문제 풀이 이전 문제와 다른 점은 입력 값이 음수 범위도 포함한다는 점이다. 하지만 코드 자체는 차이가 없다. 코드 #include using namespace std; int n; int arr[1000001], dp[1000001]; int binary(int left, int right, int key) { int mid; while (left = key) ri.. 2021. 6. 22.
[C++] 백준 12015번 : 가장 긴 증가하는 부분 수열2 https://www.acmicpc.net/problem/12015 12015번: 가장 긴 증가하는 부분 수열 2 첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000,000)이 주어진다. 둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ Ai ≤ 1,000,000) www.acmicpc.net 문제 풀이 이전 문제와 다른 점은 input의 개수이다. 따라서 이 문제의 핵심은 시간 복잡도를 줄이는 것이다. 이전 문제에서는 i - 1 회의 반복횟수로 시간 복잡도가 O(N^2)가 된다. 하지만 백만개의 인풋에 대해서 1초라는 시간 내로 연산을 끝낼 수가 없어 다른 방법으로 시도해야 한다. 이중 탐색문으로 lower bound를 찾는 방법을 이용하면 시간 복잡도가 O(N log N)이 된다. .. 2021. 6. 21.