凸多边形的划分

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;
}
原文地址:https://www.cnblogs.com/jjl0229/p/12641388.html