JonghoonAn
어제보다 하나 더
JonghoonAn
전체 방문자
오늘
어제
  • 분류 전체보기
    • 알고리즘
    • 프로젝트
    • 배운점
    • ML
    • 학교 공부
      • OS
      • 네트워크
      • 시스템 프로그래밍
      • 데이터베이스
      • 소프트웨어 분석 및 설계

블로그 메뉴

  • 홈
  • 알고리즘
  • 배운점
  • 학교 공부
  • 머신러닝

공지사항

인기 글

태그

  • 활성화 함수
  • convolutional neural network
  • activation function
  • convolutional network
  • convolutional layer
  • 합성곱
  • 학습률
  • lecture6
  • lecture7
  • CS231
  • 인공지능 학습
  • pooling
  • 인공 신경망
  • lecture10
  • lecture9
  • 역전파
  • Learning rate
  • 전이 학습
  • cs231n
  • 인공신경망
  • recurrent network
  • rnn
  • 인공지능
  • conv
  • CNN Architecture
  • neural network
  • ConvNets
  • 가중치 초기화
  • Transfer learning
  • Backpropagation

최근 댓글

최근 글

티스토리

JonghoonAn

어제보다 하나 더

Parametric search algorithm, 2805 백준
알고리즘

Parametric search algorithm, 2805 백준

2021. 3. 17. 01:34

알고리즘 분석

파라메트릭 서치 알고리즘이란?

In the design and analysis of algorithms for combinatorial optimization, parametric search is a technique for transforming a decision algorithm (does this optimization problem have a solution with quality better than some given threshold?) into an optimization algorithm (find the best solution).

 -> 결정 알고리즘을 최적화 알고리즘으로 변형해주는 알고리즘이다.

이때 결정 문제를 해결하여 최적의 값을 얻기 위해소서는 정답의 후보군이 정렬되어있어야하고, 각 원소들에 대해서 결정함수(최적의 값 X'가 현재의 값 X보다 큰가? 같은가? 작은가? 를 결정해주는 함수)가 정의되어 있어야 한다.

정리하자면 모든 정답 후보군 중에서 이분탐색과 같이 중앙의 값을 선택하고 그 값에 대하여 결정 알고리즘을 시행 한 후 시행한 결과에 따라 정답 후보군을 조정한다. 이 과정을 여러번 반복한다.

 

문제

문제 분석

문제의 요점은 input[i]  > x 인 모든 i에 대하여 sum(input[i]-x) >= m을 만족하는 x의 최댓값을 구하는 것이다.

그렇다면 정답의 후보군은 어떻게 될까? 문제에 따르면 "모든 나무의 길이의 합이 m보다 같거나 클것이다." 라는  구절로 인해 최소 후보값은 0일것이고 "M>=1"이라는 조건에 의하여 최대 후보값은 input_max-1일것이다.

그렇다면 input[i]  > x 인 모든 i에 대하여 sum(input[i]-x)을 A라고 할 때, A >= m이라면 A의 값을 줄여야 하고(즉, 자르는 높이의 최소범위를 높여야 한다), A<m이라면 A의 값을 높여야 한다(즉, 자르는 높이의 최대 범위를 낮춰야 한다.)

이를 이분탐색을 이용하여 더 빠르게 풀어보았다. (안쓴다면 O(N)이지만, 쓰면 O(logN), 입력 후보 범위가 매우 크므로 유의미 할 것이다)

내가 생각할 때 파라메트릭 서치의 가장 중요한 포인트는 두가지 인것 같다.

1. 정답 범위 산정

2. 결정 알고리즘의 구현

3. 결정 알고리즘을 통한 범위 적용

코드

#include<stdlib.h>
#include<iostream>
#include<string.h>
#include<string>
#include<vector>
#include<stack>
#include<queue> // priority_queue 포함
#include<set>
#include<unordered_set>
#include<map>
#include<unordered_map>

#include<algorithm>
#include<math.h>
#include<climits> // 자료형 limit포함

using namespace std;

typedef long long int lld;
typedef unsigned long long int uld;
typedef unsigned int ui;

const int MY_INT_MAX = 2000000000;
vector<lld> input_v;
lld n,m;

lld param_search(lld param_min, lld param_max)
{
    lld now_min = param_min;
    lld now_max = param_max;
    lld tmp_m = 0;
    while(now_min <= now_max)
    {
        lld mid = (now_min + now_max)/2;
        lld now_m = 0;
        for(lld i=0; i<input_v.size(); i++)
        {
            if(input_v[i] > mid)
                now_m += (input_v[i] - mid);
        }

        if(now_m < m)
            now_max = mid-1;
        else if(now_m >= m)
        {
            tmp_m = max(tmp_m, mid);
            now_min = mid+1;
        }
    }
    return tmp_m;
}

void solution()
{
    // code
    cin >> n >> m;
    lld input_max = 0;
    for(int i=0; i<n; i++)
    {
        lld tmp;
        cin >> tmp;
        input_max = max(input_max, tmp);
        input_v.push_back(tmp);
    }
    cout << param_search(0, input_max);
}

int main ()
{
    iostream::sync_with_stdio(0); // 이제 C stdio의 입출력 사용 불가
    cin.tie(NULL);
    cout.tie(NULL); // 개행도 \n로 하도록 하자.
    solution();
    return 0;
}

개선점?

값의 범위를 좀만 더 자세히 봐야겠다.

난이도가 낮다고 대충 넘기지 말고 모든 값에 대하여 나타날 수 있는 값을 생각한 후 자료형을 결정하자.

 

 

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

'알고리즘' 카테고리의 다른 글

백준 1655 가운데를 말해요  (0) 2021.03.19
프로그래머스 42895 N으로 표현  (1) 2021.03.17
13270 백준 피보나치 치킨  (0) 2021.03.15
백준 11054 번 가장 긴 바이토닉 부분 수열  (0) 2021.03.14
2633 백준  (0) 2021.03.11
    '알고리즘' 카테고리의 다른 글
    • 백준 1655 가운데를 말해요
    • 프로그래머스 42895 N으로 표현
    • 13270 백준 피보나치 치킨
    • 백준 11054 번 가장 긴 바이토닉 부분 수열
    JonghoonAn
    JonghoonAn
    https://github.com/jjong0225 숭실대 소프트
    hELLO. 티스토리 스킨을 소개합니다.
    제일 위로

    티스토리툴바