https://loj.ac/problem/10149
题目描述
有一个\(N\)个顶点的多边形,每个顶点都有一个权值,求如何划分使得划分后的\(N-2\)个三角形的权值乘积和最小。
思路
这题本意是要写高精度的,不过这不是重点。我们考虑用\(f[i][j]\)表示以\(i\)和\(j\)之间的顶点所构成的多边形的最小权值乘积和,那么我们考虑作为\((i,j)\)这条边,必定有一个顶点与这条边形成一个三角形,我们枚举这个点,就把这个多边形分成了两个多边形,再加上这个三角形堆答案的贡献即可。
代码
#include <bits/stdc++.h> using namespace std; typedef __int128 ll; ll read() { ll res=0,w=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9'){res=(res<<3)+(res<<1)+(ch^48);ch=getchar();} return res*w; } void write(ll x) { if(x<0){putchar('-');x=-x;} if(x>9)write(x/10); putchar(x%10+'0'); } void writeln(ll x) { write(x); putchar('\n'); } ll f[110][110],a[110]; int main() { int n=read(); for(int i=1;i<=n;i++) a[i]=read(),a[i+n]=a[i]; memset(f,127,sizeof(f)); for(int i=1;i<n*2;i++) f[i][i+1]=0; for(int len=3;len<=n;len++) for(int l=1;l<=n*2-len+1;l++) { int r=l+len-1; for(int k=l+1;k<r;k++) f[l][r]=min(f[l][r],f[l][k]+f[k][r]+a[l]*a[k]*a[r]); } ll ans=f[1][n]; for(int i=1;i<=n;i++) ans=min(ans,f[i][i+n-1]); write(ans); return 0; }