분할 정복 알고리즘이란?

2023. 2. 1. 22:17·PS/분할 정복 알고리즘[Divide & Conquer]
  • 분할 정복은 문제를 2개 또는 그 이상의 작은 부분 문제로 나눈 다음 푸는 것(분할)
  • DP의 경우는 작은 부분문제가 중복이 되므로 Memorization을 통해 중복을 제거하고, 분할 정복은 문제를 나누었는데, 중복이 되지 않기에 한 번만 풀어주면 가능
  • 푼 다음에 다시 합쳐서 정답을 구하는 경우(정복)
  • 예시 : 퀵 소트, 머지 소트, 큰 수 곱셈..

대표적인 알고리즘 

1. 이분 탐색 (Binary Search)

정렬되어 있는 리스트에서 어떤 값을 빠르게 찾는 알고리즘

리스트의 크기를 N이라고 했을 때  크기가 N인 리스트를 계속해서 절반으로 나누기 때문에, O(logN)의 시간 복잡도가 걸리게 됩니다.

 

<코드>

while(left<=right) {
    int mid = (left + right) / 2;
    if(a[mid]== x) {
        position = mid;
        break;
    } else if(a[mid]>x) {
        right = mid-1;
    } else {
        left = mid+1;
    }
}

중간값보다 작으면 right = mid -1, 중간값보다 크다면 left = mid + 1 해주면 됩니다.

 

상한과 하한에 대해서

상한 : 큰 수 중 첫 번째 수(upper_bound) 초과 

하한 : 크거나 같은 수 중 첫 번째 수(lower_bound) 이상

https://www.acmicpc.net/problem/10816

 

10816번: 숫자 카드 2

첫째 줄에 상근이가 가지고 있는 숫자 카드의 개수 N(1 ≤ N ≤ 500,000)이 주어진다. 둘째 줄에는 숫자 카드에 적혀있는 정수가 주어진다. 숫자 카드에 적혀있는 수는 -10,000,000보다 크거나 같고, 10,

www.acmicpc.net

이 문제는 카드에 적혀있는 숫자가 상근이가 몇 개 가지고 있는지 개수를 출력하는 문제입니다.

<코드>

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	
	int n;
	cin>>n;
	vector<int> a(n);
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
	}
	sort(a.begin(),a.end());
	int m;
	cin>>m;
	for(int i=0;i<m;i++){
		int num;
		cin>>num;
		cout<<upper_bound(a.begin(),a.end(),num)-lower_bound(a.begin(),a.end(),num)<<' ';
	
	}
	//상한: 큰수 중에 첫번째(초과)  하한 : 같거나 큰 수 중에 첫번째(이상) 
	cout<<'\n';
	
}

테스트케이스 중 하나인 수인 10을 기준으로 upper_bound(10)은 10을 초과하는 인덱스이기 때문에 9가 나오게 되고, 

lower_bound(10)은 10 이상의 수가 처음 나오는 인덱스이기 때문에 6이 됩니다. 

저작자표시 비영리 변경금지 (새창열림)

'PS > 분할 정복 알고리즘[Divide & Conquer]' 카테고리의 다른 글

백준 1780 종이의 개수(c++)  (0) 2023.02.03
백준 1914 하노이 탑(c++)  (0) 2023.02.03
'PS/분할 정복 알고리즘[Divide & Conquer]' 카테고리의 다른 글
  • 백준 1780 종이의 개수(c++)
  • 백준 1914 하노이 탑(c++)
SeungbeomKim
SeungbeomKim
[IT(PS, CS, SW, etc.) 지식 기록] Github : https://github.com/daily1313/
  • SeungbeomKim
    개발 블로그
    SeungbeomKim
  • 전체
    오늘
    어제
    • 분류 전체보기 (383)
      • 일상 (33)
        • 여행 (17)
        • 회고록 (9)
        • 리뷰 (7)
      • PS (138)
        • 그리디 알고리즘[Greedy] (25)
        • 정렬 알고리즘[Sort] (18)
        • 문자열 알고리즘[String] (14)
        • 동적 계획 알고리즘[DP] (17)
        • 깊이 우선 탐색, 너비 우선 탐색[DFS, BFS.. (34)
        • 재귀[Recursion] (2)
        • 백트래킹[Backtracking] (5)
        • 브루트포스 알고리즘[Bruteforce] (16)
        • 자료 구조[Data Structure] (4)
        • 분할 정복 알고리즘[Divide & Conquer.. (3)
      • CS (22)
      • Network (11)
      • Database (8)
        • Elasticsearch (3)
      • Linux (2)
      • JavaScript (4)
        • AngularJS (1)
      • Java (92)
        • Effective Java (5)
        • Java Concept (20)
        • Spring (61)
        • Design Pattern (3)
      • Python (2)
      • Vscode (1)
      • DevOps (43)
        • AWS (27)
        • Git (7)
        • Docker (6)
        • Nginx (1)
      • 자격증 (10)
        • SQL (4)
      • 사이드 프로젝트 (2)
        • MatJido (2)
      • 기타 (9)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 소개
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    컴퓨터구조
    정보처리기사
    일본여행
    메타코딩
    정보처리기사 실기
    dp
    Effective Java
    백트래킹
    다이나믹 프로그래밍
    sqld
    너비 우선 탐색
    dfs
    정보처리기사 필기
    AWS
    docker
    이펙티브 자바
    Spring
    BFS
    Wi-Fi
    springboot
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
SeungbeomKim
분할 정복 알고리즘이란?
상단으로

티스토리툴바