𝘚𝘭𝘰𝘸 𝘣𝘢𝘡 𝘴𝘡𝘦𝘒π˜₯𝘺

[λ°±μ€€] 1699번: 제곱수의 ν•© - C++ λ³Έλ¬Έ

μ½”λ”©ν…ŒμŠ€νŠΈ μ€€λΉ„/λ°±μ€€

[λ°±μ€€] 1699번: 제곱수의 ν•© - C++

.23 2021. 7. 30. 01:37
문제

μ–΄λ–€ μžμ—°μˆ˜ N은 그보닀 μž‘κ±°λ‚˜ 같은 μ œκ³±μˆ˜λ“€μ˜ ν•©μœΌλ‘œ λ‚˜νƒ€λ‚Ό 수 μžˆλ‹€. 예λ₯Ό λ“€μ–΄ 11=32+12+12(3개 ν•­)이닀. 이런 ν‘œν˜„λ°©λ²•μ€ μ—¬λŸ¬ 가지가 될 수 μžˆλŠ”λ°, 11의 경우 11=22+22+12+12+12(5개 ν•­)도 κ°€λŠ₯ν•˜λ‹€. 이 경우, μˆ˜ν•™μž μˆŒν¬λΌν…ŒμŠ€λŠ” “11은 3개 ν•­μ˜ 제곱수 ν•©μœΌλ‘œ ν‘œν˜„ν•  수 μžˆλ‹€.”라고 λ§ν•œλ‹€. λ˜ν•œ 11은 그보닀 적은 ν•­μ˜ 제곱수 ν•©μœΌλ‘œ ν‘œν˜„ν•  수 μ—†μœΌλ―€λ‘œ, 11을 κ·Έ ν•©μœΌλ‘œμ¨ ν‘œν˜„ν•  수 μžˆλŠ” 제곱수 ν•­μ˜ μ΅œμ†Œ κ°œμˆ˜λŠ” 3이닀.

주어진 μžμ—°μˆ˜ N을 μ΄λ ‡κ²Œ μ œκ³±μˆ˜λ“€μ˜ ν•©μœΌλ‘œ ν‘œν˜„ν•  λ•Œμ— κ·Έ ν•­μ˜ μ΅œμ†Œκ°œμˆ˜λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

 

μž…λ ₯

첫째 쀄에 μžμ—°μˆ˜ N이 주어진닀. (1 ≤ N ≤ 100,000)

 

좜λ ₯

주어진 μžμ—°μˆ˜λ₯Ό 제곱수의 ν•©μœΌλ‘œ λ‚˜νƒ€λ‚Ό λ•Œμ— κ·Έ 제곱수 ν•­μ˜ μ΅œμ†Œ 개수λ₯Ό 좜λ ₯ν•œλ‹€.


DPλ₯Ό μ΄μš©ν•˜μ—¬ ν’€ 수 μžˆλŠ” 문제.

μ²˜μŒμ— μ ‘κ·Όν–ˆλ˜ 방식은 N보닀 μž‘μ€ 수 쀑 κ°€μž₯ 큰 μ œκ³±μˆ˜λΆ€ν„° λΉΌλ‚˜κ°€λŠ” λ°©μ‹μ΄μ—ˆλŠ”λ°, κ·Έλ ‡κ²Œ ν–ˆλ”λ‹ˆ 닡이 λ‹€λ₯΄κ²Œ λ‚˜μ˜€λŠ” κ²½μš°λ“€μ΄ λ§Žμ•˜λ‹€. μ–΄μ¨Œκ±°λ‚˜ 닡이 μ œλŒ€λ‘œ λ‚˜μ˜€μ§€ μ•ŠλŠ”λ‹€λŠ” 것은 μ ‘κ·Ό 방식이 ν‹€λ Έλ‹€λŠ” 것이기 λ•Œλ¬Έμ—, λ‹€λ₯Έ 방법을 μƒκ°ν•΄μ€˜μ•Όν•œλ‹€.

 

κ΅¬κΈ€μ˜ νž˜μ„ 빌린 κ²°κ³Ό, 제곱수 ν•­μ˜ μ΅œμ†Œ 개수λ₯Ό κ΅¬ν•΄μ£ΌλŠ” 방식은 λ‹€μŒκ³Ό κ°™λ‹€.

1λΆ€ν„° NκΉŒμ§€μ˜ 제곱수 ν•­μ˜ μ΅œμ†Œ 개수λ₯Ό 담을 λ°°μ—΄ D[]λ₯Ό μ„ μ–Έν•΄μ£Όκ³ , i = j2 + (i - j2인 점을 μ΄μš©ν•˜μ—¬ N보닀 μž‘μ€ 수 쀑 κ°€μž₯ 큰 μ œκ³±μˆ˜λΆ€ν„°κ°€ μ•„λ‹Œ, κ°€μž₯ μž‘μ€ 1λΆ€ν„° λΉΌκ°€λ©° κ°€μž₯ μ΅œμ†Œκ°€ λ˜λŠ” D[i]의 값을 λΉ„κ΅ν•œλ‹€.

이 λ•Œ, D[j2]λŠ” 항상 1이 되기 λ•Œλ¬Έμ— 기쑴의 D[i]와 D[i - j2] + 1의 값을 비ꡐ해가며 항이 μ΅œμ†Œ κ°œμˆ˜κ°€ λ˜λŠ” 경우λ₯Ό μ €μž₯ν•΄μ€€λ‹€.

 

항상 D[i]λŠ” i보닀 μž‘μ€ 값이 되기 λ•Œλ¬Έμ—, μ²˜μŒμ—λŠ” D[i] = i둜 μ΄ˆκΈ°ν™”ν•΄μ€€λ‹€.

18을 예둜 λ“€μ–΄λ³΄μž.

 

1. D[18] = min(D[18], D[17] + 1), D[17] = 2 ( 42 + 12 )

    D[18] = min(18, 3) = 3

2. D[18] = min(D[18], D[14] + 1), D[14] = 3 ( 32 + 22 + 12 )

    D[18] = min(3, 4) = 3

3. D[18] = min(D[18], D[9] + 1)

    D[18] = min(3, 2) = 2

4. D[18] = min(D[18], D[2] + 1)

    D[18] = min(2, 3) = 2

 

λ”°λΌμ„œ, D[18] = 2 ( 32 + 32 )κ°€ λœλ‹€.

 

μ½”λ“œ
#include <cstdio>
#include <vector>
#include <cmath>

using namespace std;

int DP(int num);
int min(int a, int b) { return a < b ? a : b; }

int main(void) {
    int n;
    scanf("%d", &n);
    printf("%d\n", DP(n));
    return 0;
}

int DP(int num) {
    vector<int> D(num + 1, 0);
    for(int i = 1; i <= num; i++) {
        D[i] = i;
    }

    for(int i = 1; i <= num; i++) {
        for(int j = 1; j * j <= i; j++) {
            D[i] = min(D[i], D[i - j * j] + 1);
        }
    }
    return D[num];
}
Comments