문제

문제 분류 : dp

코드

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <utility>
using namespace std;

int dp[1001] = { 0 };

int main() {
    cin.tie(NULL);
    cout.tie(NULL);
    ios::sync_with_stdio(false);
    int num;
    int max = 0;
    int max_dp = 1;
    int temp = 0;
    vector<int> vec;
    fill_n(dp, 1001, 1);
    cin >> num;
    for (int i = 0; i < num; i++) {
        cin >> temp;
        vec.push_back(temp);
    }
    for (int i = 1; i < num; i++) {
        max = 0;
        for (int j = 0; j < i; j++) {
            if (vec[i] > vec[j]) {
                if (dp[j] > max)
                    max = dp[j];
            }
        }
        dp[i] += max;
        if (dp[i] > max_dp)
            max_dp = dp[i];
    }    
    cout << max_dp;
}

설명

이 문제를 DP로 풀기위해서 다음과 같이 접근 하였다.

  1. 모든 dp 값을 1로 초기화 한다.

    • 왜냐하면 모두가 자기 자신을 수열로 가지기 때문이다.
  2. 기준 dp 값의 이전값들을 모두 탐색하여 기준 값보다 작을 경우 max라는 변수에 작은 부분의 dp의 값과 기준 dp의 값을 더한다 (n + 1)

  3. 반복하여 만약 max 값이 새로운 값보다 작다면 max 값을 변경하고 새로운 값으로 교체한다.

예시

예제문제로 {10, 20 , 10, 30 , 20 , 50} 배열이 있을 경우

  1. dp[1]일 때

    1. dp[1] > dp [0] 이므로 dp[1] += dp[0] 이다.
  2. dp[2]일 때

    1. dp[2] == dp[0] 이므로 넘어간다.
    2. dp[2] < dp[1] 이므로 넘어간다.
  3. dp[3]일 때

    1. dp[3] > dp[0] 이므로 dp[3] += dp[0] 이다.
    2. dp[3] > dp[1] 이므로 dp[3] += dp[1] 이다.
    3. dp[3] > dp[2] 이므로 dp[3] += dp[2] 이다.

이렇게 반복해서 dp의 값중 가장 큰 값이 가장 긴 증가하는 부분 수열의 길이가 된다.

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

[BOJ] 1094번 : 01타일  (0) 2021.06.30

문제


문제의 종류는 DP 이다. 문제를 풀기위해서 타일의 개수를 세어보았다.

N = 1 일때는 1 이므로 1개이다.

N = 2 일때는 00, 11 이므로 2개이다.

N = 3 일떄는 111, 100, 001 이므로 3개이다.

N = 4 일때는 1111, 1100 , 1001, 0011 , 0000 이므로 총 5개이다.

N = 5 일때는 11111, 11100, 11001, 10011, 00111, 10000, 00100, 00001 이므로 총 8개이다.

N = 6 일때는 111111, 111100, 111001, 110011, 100111, 001111, 110000, 100100, 100001, 001100, 001001, 000011, 000000 총 13개이다.

N = 7 일때는 1111111, 0011111, 1001111, 1100111, 1110011, 1111001, 1111100, 1110000, 1100100, 1001100, 0011100, 1100001, 1000011, 0000111, 1000000, 0010000, 0000100, 0000001, 1001001, 0011001, 0011001 으로 총 13개이다.

이러한 반복을 통해 특정한 점화식을 이 식을 가진다는 것을 알 수 있다.

Dp[i] = Dp[i-1] + Dp[i-2]

이를 통해 구현 한 코드는 다음과 같다.

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <utility>
using namespace std;

int dp[1000001] = { 0,1,2,3 };

int main() {
    cin.tie(NULL);
    cout.tie(NULL);
    ios::sync_with_stdio(false);
    int num;
    for (int i = 4; i <= 1000000; i++) {
        dp[i] += (dp[i - 1] + dp[i - 2]) % 15746;
    }
    cin >> num;
    cout << dp[num];
}

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

[BOJ] 11053번 가장 긴 증가하는 부분 수열(LIS)  (0) 2021.07.02

+ Recent posts