πŸ“¦11049: ν–‰λ ¬ κ³±μ…ˆ μˆœμ„œ


[μ•Œκ³ λ¦¬μ¦˜ 풀이] κ°•λ™κ·œ
Reviewed by midade midang (devmidade12@gmail.com)
Reviewed:: 2024-02-19
문제 ν™•μΈν•˜κΈ°

풀이

  • 이 λ¬Έμ œλŠ” 1μ‹œκ°„μ„ 고민해도 μ „ν˜€ κ°ˆν”Όλ₯Ό μž‘μ§€ λͺ»ν•˜κ² μ–΄μ„œ κ²°κ΅­ https://cocoon1787.tistory.com/318의 풀이λ₯Ό μ°Έκ³ ν–ˆλ‹€. ν™•μ‹€νžˆ DP λ¬Έμ œμ— μ•½ν•˜λ‹€κ³  λŠκ»΄μ§„λ‹€.

  • dp[n][m] λŠ” n μ—μ„œ m κΉŒμ§€μ˜ λ²”μœ„λ₯Ό ν–‰λ ¬ μ—°μ‚°ν–ˆμŒμ„ μ˜λ―Έν•œλ‹€.

  • 3쀑 for 문을 μ‚¬μš©ν•˜μ—¬ ν–‰λ ¬ μ—°μ‚°μ˜ λ²”μœ„, μ‹œμž‘ 지점, λ²”μœ„ 연산을 μ§€μ •ν•΄ κ³„μ‚°ν•œλ‹€.

  • i λŠ” ν–‰λ ¬μ˜ λ²”μœ„λ₯Ό μ§€μ •ν•œλ‹€. i = 2 일 경우, dp[n][m] μ—μ„œ m-n, nκ³Ό m μ‚¬μ΄μ˜ 거리, 차이가 2λΌλŠ” λœ»μ΄λ‹€.

  • j λŠ” ν–‰λ ¬μ˜ μ‹œμž‘ 지점을 λ§ν•œλ‹€. j = 3, i = 2 인 경우 dp[3][5] 둜 3μ—μ„œ μ‹œμž‘ν•΄μ„œ 5λ²ˆμ§ΈκΉŒμ§€μ˜ 행렬을 κ΅¬ν•œλ‹€.

  • mid λŠ” λ²”μœ„ μ•ˆμ—μ„œμ˜ μ‹€μ§ˆμ μΈ 연산을 μ§„ν–‰ν•œλ‹€. dp[3][10] 을 κ΅¬ν•œλ‹€κ³  ν•˜λ©΄ mid λŠ” 3~10 의 값이고, λ°˜λ³΅λ¬Έμ„ λŒλ©΄μ„œ dp[3][3], dp[3][4], … λ₯Ό κ΅¬ν•œλ‹€.

  • μ΅œμ’…μ μœΌλ‘œλŠ” dp[1][N] 을 κ΅¬ν•˜λ©΄ 1~N κΉŒμ§€μ˜ ν–‰λ ¬ μ—°μ‚°μ˜ μ΅œμ†Ÿκ°’μ„ ꡬ할 수 μžˆλ‹€.

  • 혼자 생각할 λ•Œ dp둜 λŠλ‚Œμ΄ λ“€κΈ°λŠ” ν–ˆμ§€λ§Œ μ–΄λ–»κ²Œ ν’€μ–΄μ•Ό ν• μ§€ 감이 μ˜€μ§€ μ•Šμ•˜λ‹€. ν•΄λ‹Ή 문제λ₯Ό ν’€μ΄ν•˜λŠ” 방식이 이해λ₯Ό ν•˜λ‹ˆκΉŒ 끄덕일 수 μžˆμ—ˆμ§€λ§Œ 체득이 ν•„μš”ν•  것 κ°™λ‹€.

μ½”λ“œ

#include <iostream>
 
#define endl '\n'
using namespace std;
 
int N;
int matInfo[501][2];
int dp[501][501];
 
void Input(){
    cin >> N;
    for(int i=1; i<=N; i++) {
        cin >> matInfo[i][0] >> matInfo[i][1];
    }
}
 
void Solution(){
    for(int i=1; i<N; i++){
        for(int j=1; i+j<=N; j++){
            dp[j][i+j] = INT32_MAX;
            for(int mid=j; mid<=i+j; mid++){
				dp[j][i+j] = min(dp[j][i+j], dp[j][mid] + dp[mid+1][i+j]                         + matInfo[j][0]*matInfo[mid][1]*matInfo[i+j][1]);
            }
        }
    }
    cout << dp[1][N] << endl;
}
 
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
 
    Input();
    Solution();
 
    return 0;
}