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

[λ°±μ€€] 2579번: 계단 였λ₯΄κΈ° - C++ λ³Έλ¬Έ

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

[λ°±μ€€] 2579번: 계단 였λ₯΄κΈ° - C++

.23 2021. 7. 18. 00:09
문제

계단 였λ₯΄κΈ° κ²Œμž„μ€ 계단 μ•„λž˜ μ‹œμž‘μ λΆ€ν„° 계단 κΌ­λŒ€κΈ°μ— μœ„μΉ˜ν•œ λ„μ°©μ κΉŒμ§€ κ°€λŠ” κ²Œμž„μ΄λ‹€. <κ·Έλ¦Ό 1>κ³Ό 같이 각각의 κ³„λ‹¨μ—λŠ” μΌμ •ν•œ μ μˆ˜κ°€ μ“°μ—¬ μžˆλŠ”λ° 계단을 밟으면 κ·Έ 계단에 μ“°μ—¬ μžˆλŠ” 점수λ₯Ό μ–»κ²Œ λœλ‹€.

<κ·Έλ¦Ό 1>

 

예λ₯Ό λ“€μ–΄ <κ·Έλ¦Ό 2>와 같이 μ‹œμž‘μ μ—μ„œλΆ€ν„° 첫 번째, 두 번째, λ„€ 번째, μ—¬μ„― 번째 계단을 λ°Ÿμ•„ 도착점에 λ„λ‹¬ν•˜λ©΄ 총 μ μˆ˜λŠ” 10 + 20 + 25 + 20 = 75점이 λœλ‹€.

<κ·Έλ¦Ό 2>

계단 였λ₯΄λŠ” λ°λŠ” λ‹€μŒκ³Ό 같은 κ·œμΉ™μ΄ μžˆλ‹€.

  1. 계단은 ν•œ λ²ˆμ— ν•œ 계단씩 λ˜λŠ” 두 계단씩 였λ₯Ό 수 μžˆλ‹€. 즉, ν•œ 계단을 λ°ŸμœΌλ©΄μ„œ μ΄μ–΄μ„œ λ‹€μŒ κ³„λ‹¨μ΄λ‚˜, λ‹€μŒ λ‹€μŒ κ³„λ‹¨μœΌλ‘œ 였λ₯Ό 수 μžˆλ‹€.
  2. μ—°μ†λœ μ„Έ 개의 계단을 λͺ¨λ‘ λ°Ÿμ•„μ„œλŠ” μ•ˆ λœλ‹€. 단, μ‹œμž‘μ μ€ 계단에 ν¬ν•¨λ˜μ§€ μ•ŠλŠ”λ‹€.
  3. λ§ˆμ§€λ§‰ 도착 계단은 λ°˜λ“œμ‹œ λ°Ÿμ•„μ•Ό ν•œλ‹€.

λ”°λΌμ„œ 첫 번째 계단을 밟고 이어 두 번째 κ³„λ‹¨μ΄λ‚˜, μ„Έ 번째 κ³„λ‹¨μœΌλ‘œ 였λ₯Ό 수 μžˆλ‹€. ν•˜μ§€λ§Œ, 첫 번째 계단을 밟고 이어 λ„€ 번째 κ³„λ‹¨μœΌλ‘œ μ˜¬λΌκ°€κ±°λ‚˜, 첫 번째, 두 번째, μ„Έ 번째 계단을 μ—°μ†ν•΄μ„œ λͺ¨λ‘ λ°Ÿμ„ μˆ˜λŠ” μ—†λ‹€.

각 계단에 μ“°μ—¬ μžˆλŠ” μ μˆ˜κ°€ μ£Όμ–΄μ§ˆ λ•Œ 이 κ²Œμž„μ—μ„œ 얻을 수 μžˆλŠ” 총 점수의 μ΅œλŒ“κ°’μ„ κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

 

μž…λ ₯

μž…λ ₯의 첫째 쀄에 κ³„λ‹¨μ˜ κ°œμˆ˜κ°€ 주어진닀.

λ‘˜μ§Έ 쀄뢀터 ν•œ 쀄에 ν•˜λ‚˜μ”© 제일 μ•„λž˜μ— 놓인 계단뢀터 μˆœμ„œλŒ€λ‘œ 각 계단에 μ“°μ—¬ μžˆλŠ” μ μˆ˜κ°€ 주어진닀. κ³„λ‹¨μ˜ κ°œμˆ˜λŠ” 300μ΄ν•˜μ˜ μžμ—°μˆ˜μ΄κ³ , 계단에 μ“°μ—¬ μžˆλŠ” μ μˆ˜λŠ” 10,000μ΄ν•˜μ˜ μžμ—°μˆ˜μ΄λ‹€.

 

좜λ ₯

첫째 쀄에 계단 였λ₯΄κΈ° κ²Œμž„μ—μ„œ 얻을 수 μžˆλŠ” 총 점수의 μ΅œλŒ“κ°’μ„ 좜λ ₯ν•œλ‹€.

 


DPλ₯Ό μ΄μš©ν•˜λŠ” 문제.

2156번 포도주 μ‹œμ‹λ¬Έμ œμ™€ λ™μΌν•˜κ²Œ μ ‘κ·Όν•˜μ§€λ§Œ, 쑰금 더 κ°„λ‹¨ν•œ λ¬Έμ œμ΄λ‹€.

 

계단은 ν•œλ²ˆμ— ν•œ μΉΈμ΄λ‚˜ 두 μΉΈκΉŒμ§€λ§Œ 이동할 수 있고, μ„Έ 칸을 연달아 였λ₯΄λŠ” 것은 λΆˆκ°€λŠ₯ν•˜λ‹€. λ”°λΌμ„œ n번째 계단을 밟게 될 차둀라고 ν–ˆμ„ λ•Œ κ°€λŠ₯ν•œ 상황은 λ‹€μŒκ³Ό κ°™λ‹€.

 

  1. (n - 1)번째 계단을 λ°Ÿμ§€ μ•Šμ€ 경우
  2. (n - 1)번째 계단을 λ°Ÿμ•˜μ„ 경우

1의 경우 n번째 κ³„λ‹¨κΉŒμ§€μ˜ μ μˆ˜λŠ” (n - 2)번째 계단을 λ°Ÿμ•˜μ„ λ•Œ κΉŒμ§€μ˜ 점수 합에 n번째 κ³„λ‹¨μ˜ 점수λ₯Ό 더해주면 λœλ‹€. 이λ₯Ό μ‹μœΌλ‘œ ν‘œν˜„ν•˜λ©΄ λ‹€μŒκ³Ό κ°™λ‹€.

 

D[n] = D[n - 2] + stair[n]

 

2의 경우 연달아 μ„Έ 계단을 λ°ŸλŠ” 것이 λΆˆκ°€λŠ₯ν•˜λ―€λ‘œ (n - 2)번째 계단은 κ±΄λ„ˆ λ›΄ μ…ˆμ΄ λœλ‹€. λ”°λΌμ„œ (n - 3)번째 계단을 λ°Ÿμ•˜μ„ λ•Œ κΉŒμ§€μ˜ 점수 합에 (n - 1)번째 κ³„λ‹¨μ˜ μ μˆ˜μ™€ n번째 κ³„λ‹¨μ˜ 점수λ₯Ό 더해쀀닀. 이λ₯Ό μ‹μœΌλ‘œ ν‘œν˜„ν•˜λ©΄ λ‹€μŒκ³Ό κ°™λ‹€.

 

D[n] = D[n - 3] + stair[n - 1] + stair[n]

 

1κ³Ό 2 쀑 μ–΄λŠ κ²½μš°μ— 점수의 합이 더 큰지 μ•Œ 수 μ—†κΈ° λ•Œλ¬Έμ— κ°’ 비ꡐλ₯Ό 톡해 D[n]을 μ΅œμ’…μ μœΌλ‘œ κ²°μ •ν•΄μ€€λ‹€. λ”°λΌμ„œ 이 문제의 점화식은 λ‹€μŒκ³Ό κ°™λ‹€.

 

D[n] = max(D[n - 2] + stair[n], D[n - 3] + stair[n - 1] + stair[n])

 

두 칸을 μ—°μ†μœΌλ‘œ λ›°μ–΄λ„˜μ„ 수 μ—†κ³ , λ§ˆμ§€λ§‰ 계단은 λ°˜λ“œμ‹œ λ°Ÿμ•„μ•Ό ν•œλ‹€λŠ” 쑰건 λ•Œλ¬Έμ— 포도주 μ‹œμ‹ λ¬Έμ œμ™€ 쑰금 식이 달라진닀. μ•žμ„œ 예λ₯Ό λ“€μ—ˆλ˜ { 10, 13, 1, 2, 5, 11 }  은 포도주 μ‹œμ‹ λ¬Έμ œμ—μ„œλŠ” 39κ°€ λ‚˜μ˜€μ§€λ§Œ, 이 λ¬Έμ œμ—μ„œλŠ” μœ„μ˜ μ‘°κ±΄λ•Œλ¬Έμ— 36이 λ‚˜μ˜€λŠ” 것이 λ§žλ‹€.

 

λ¬Έμ œλŠ” bottom-up λ°©μ‹μœΌλ‘œ ν’€μ—ˆλ‹€.

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

using namespace std;

int DP(int num);
int max(int num1, int num2) { return num1 > num2 ? num1 : num2; }

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

int DP(int num) {
    vector<int> stair(num + 1, 0);
    vector<int> score(num + 1, 0);

    for(int i = 1; i <= num; i++) {
        scanf("%d", &stair[i]);
    }

    if(num >= 1) score[1] = stair[1];
    if(num >= 2) score[2] = stair[1] + stair[2];
    
    for(int i = 3; i <= num; i++) {
        score[i] = max(score[i - 2] + stair[i], score[i - 3] + stair[i - 1] + stair[i]);
    }

    return score[num];
}
Comments