セクションdp POJ 1651乗算パズルセクションDP

POJ 1651乗算パズルセクションDP

一連の数値が与えられた場合、コストを最小限に抑えるために、途中にあるすべての数値を削除するようにしてください。数値の1つを取得するコストは、この数値とその左右の積です。

解決策:

定期的な間隔DP、列挙間隔の長さ、列挙の開始点、および列挙分割点(ここでの分割点とは、範囲内で最後に取り除かれる数を示す分割点です!この質問で検討する唯一の点である可能性があります)の書き込みを考慮してください。

dp [i] [j]がiからjまでのすべての数値の最小コストを表し、a [i]が位置iの数値を表すとします。

dp [i] [j] = min(dp [i] [k-1] + dp [k + 1] [j] + a [i-1] * a [k] * a [j + 1])( k = i ... j-1)

最小値が考慮されるため、配列は次のように前処理する必要があります。

dp [i] [i-1] = 0;

dp [i] [i] = a [i] * a [i + 1] * a [i-1]

その他のdp [i] [j] = INF;

#include <iostream> 
#include <cstring> 
#include <stdio.h> 
#include <algorithm> 
using namespace std; 
const int N = 105; 
int dp [N] [N]; 
int a [N]; 
int main()
{ 
    int n; 
    scanf( "%d"、&n); 
    for(int i = 0; i <n; i ++){ 
        scanf( "%d"、&a [i]); 
    } 
    
    memset(dp、0x3f、sizeof(dp)); 
    for(int i = 1; i <n; i ++)
        dp [i] [i-1] = 0; 
    for(int i = 1; i <n-1; i ++){ 
        dp [i] [i] = a [i] * a [i-1] * a [i + 1]; 
    } 
    for(int len = 1; len <= n-2; len ++){ 
        for(int i = 1; i + len-1 <n-1; 
            int end = i + len-1;
            for(int k = i; k <= end; k ++){ 
                dp [i] [end] = min(dp [i] [end]、dp [i] [k-1] + dp [k + 1] [ end] + a [k] * a [i-1] * a [end + 1]); 
            } 
        } 
    } 
    printf( "%d \ n"、dp [1] [n-2]); 
    0を返します。
}

  

一連の数値が与えられた場合、コストを最小限に抑えるために、途中にあるすべての数値を削除するようにしてください。数値の1つを取得するコストは、この数値とその左右の積です。

解決策:

定期的な間隔DP、列挙間隔の長さ、列挙の開始点、および列挙分割点(ここでの分割点とは、範囲内で最後に取り除かれる数を示す分割点です!この質問で検討する唯一の点である可能性があります)の書き込みを考慮してください。

dp [i] [j]がiからjまでのすべての数値の最小コストを表し、a [i]が位置iの数値を表すとします。

dp [i] [j] = min(dp [i] [k-1] + dp [k + 1] [j] + a [i-1] * a [k] * a [j + 1])( k = i ... j-1)

最小値が考慮されるため、配列は次のように前処理する必要があります。

dp [i] [i-1] = 0;

dp [i] [i] = a [i] * a [i + 1] * a [i-1]

その他のdp [i] [j] = INF;

#include <iostream> 
#include <cstring> 
#include <stdio.h> 
#include <algorithm> 
using namespace std; 
const int N = 105; 
int dp [N] [N]; 
int a [N]; 
int main()
{ 
    int n; 
    scanf( "%d"、&n); 
    for(int i = 0; i <n; i ++){ 
        scanf( "%d"、&a [i]); 
    } 
    
    memset(dp、0x3f、sizeof(dp)); 
    for(int i = 1; i <n; i ++)
        dp [i] [i-1] = 0; 
    for(int i = 1; i <n-1; i ++){ 
        dp [i] [i] = a [i] * a [i-1] * a [i + 1]; 
    } 
    for(int len = 1; len <= n-2; len ++){ 
        for(int i = 1; i + len-1 <n-1; 
            int end = i + len-1;
            for(int k = i; k <= end; k ++){ 
                dp [i] [end] = min(dp [i] [end]、dp [i] [k-1] + dp [k + 1] [ end] + a [k] * a [i-1] * a [end + 1]); 
            } 
        } 
    } 
    printf( "%d \ n"、dp [1] [n-2]); 
    0を返します。
}

  

おすすめ

転載: www.cnblogs.com/hgangang/p/12741847.html