凸多边形的划分

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('
');
}

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