给定一个具有N(N<50)个顶点(从1到N编号)的凸多边形,每个顶点的权均已知。问如何把这个凸多边形划分成N-2个互不相交的三角形,使得这些三角形顶点的权的乘积之和最小?
输入文件:第一行 顶点数N
第二行 N个顶点(从1到N)的权值
输出格式:最小的和的值
样例:5
1 2 3 4 5
输出:38
1 /*没找到交的OJ网站,就自己造了几组数据试了一下 2 区间型DP的转移方程:一般涉及区间的起点和延伸的长度 3 f[i][j]表示从i开始j长度的区间分割三角形的最小乘积和,把端点i,i+j-1可以与区间内任意一个不与i,i+j-1相邻的点组成三角形,所以枚举中间点k即可*/ 4 #include<iostream> 5 using namespace std; 6 #include<cstdio> 7 #include<cstring> 8 #define N 120 9 #define MAX (1<<31)-1 10 long long a[N]; 11 long long f[N][N]; 12 int n; 13 int main() 14 { 15 scanf("%d",&n); 16 for(int i=1;i<=n;++i) 17 { 18 scanf("%d",&a[i]); 19 a[i+n]=a[i];/*把这条多边形变成两倍的链条*/ 20 } 21 memset(f,127,sizeof(f)); 22 for(int i=1;i<=2*n-2;++i) 23 f[i][3]=a[i]*a[i+1]*a[i+2];/*初始化*/ 24 for(int j=4;j<=n;++j) 25 for(int i=1;i+j<=2*n+1;++i) 26 for(int k=i+2;i+j-k>=3;++k)/*枚举k*/ 27 f[i][j]=min(f[i][j],f[i][k-i+1]+f[k][i+j-k]+a[i]*a[k]*a[i+j-1]); 28 long long ans=MAX; 29 for(int i=1;i<=n;++i)/*注意最后把所有点作为区间端点长度为n的情况都枚举,找出最小值*/ 30 ans=min(ans,f[i][n]); 31 cout<<ans<<endl; 32 return 0; 33 }
时间: 2024-10-05 22:28:47