poj1651 Multiplication Puzzle(區間dp)
阿新 • • 發佈:2018-12-12
題意:
給出一系列數字,除了頭尾不能動,每次去除一個數字,這個數字左右相鄰數字的乘積是其價值,最後將所有價值加起來,要求最小值
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; }