1069. 凸多邊形的划分
給定一個具有 N 個頂點的凸多邊形,將頂點從 1 至 N 標號,每個頂點的權值都是一個正整數。
將這個凸多邊形划分成 N−2 個互不相交的三角形,對於每個三角形,其三個頂點的權值相乘都可得到一個權值乘積,試求所有三角形的頂點權值乘積之和至少為多少。
輸入格式
第一行包含整數 N,表示頂點數量。
第二行包含 N 個整數,依次為頂點 1 至頂點 N 的權值。
輸出格式
輸出僅一行,為所有三角形的頂點權值乘積之和的最小值。
數據范圍
N≤50,
數據保證所有頂點的權值都小於109
輸入樣例:
5
121 122 123 245 231
輸出樣例:
12214884
思路: 多邊形的一條邊[l,r]一定會在某個三角形中,而它的邊對着的點在[l+1,r-1]之間,我們看圖可以發現,一個三角形可以把一個多邊形分成兩個多邊形,以(1,7)為邊,連接4的綠色三角形把圖分成了[1,4]和[4,7]的多邊形,由於三角形之間不能有交叉,所以左邊多邊形怎么划分和右邊怎么划分沒關系,所以區間[1,7]的多邊形就分成了[1,4]和[4,7]兩個多邊形。
這道題很容易被想成環形DP,但其實最終的答案只有f[1,n]。因為對於(1,n)這條邊的划分可以在任意[2,n-1]之間的任一點,也就是把所有情況都考慮了。
#include<bits/stdc++.h>
using namespace std;
const int N=105,INF=0x3f3f3f3f;
long long f[N][N],a[N];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;++i) cin>>a[i];
for(int len=3;len<=n;++len){
for(int st=1;st+len-1<=n;++st){
int ed=st+len-1;
f[st][ed]=INF;
for(int k=st+1;k<=ed-1;++k){
f[st][ed]=min(f[st][ed],f[st][k]+f[k][ed]+a[st]*a[k]*a[ed]);
}
}
}
long long res=1e18;
cout<<f[1][n]<<endl;
return 0;
}