1. 程式人生 > >poj1651 Multiplication Puzzle(區間dp)

poj1651 Multiplication Puzzle(區間dp)

題意:

給出一系列數字,除了頭尾不能動,每次去除一個數字,這個數字左右相鄰數字的乘積是其價值,最後將所有價值加起來,要求最小值

d[i][j]表示第i個數到第j個數合併的最小值

狀態轉移方程:

d[i][j]=min(d[i][j],d[i][k]+d[k][j]+a[i]*a[j]*a[k])

只能說dp博大精深,實在不懂手動模擬一下就懂了,還需練習啊

#include <iostream>
#include <cstring>
using namespace std;
const int maxn = 106;
const int INF = 0x3f3f3f3f;
int dp[maxn][maxn];
int num[maxn];
int main()
{
    int n;
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>num[i];
    }
    for(int len=2; len<=n; len++) //區間長度
    {
        for(int i=1; i+len<=n; i++) //起點
        {
            int j=i+len;
            dp[i][j]=INF;
            for(int k=i+1; k<j; k++)
                dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]+num[i]*num[k]*num[j]);
        }
    }
    cout<<dp[1][n]<<endl;
    return 0;
}