Acwing1069. 凸多边形的划分

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Acwing1069. 凸多边形的划分相关的知识,希望对你有一定的参考价值。

Acwing1069. 凸多边形的划分

题意:

一个N个顶点的凸多边形,划分成N-2个互不相交的三角形,对于每个三角形,其三个顶点的权值相乘都可得到一个权值乘积,试求所有三角形的顶点权值乘积之和至少为多少。

题解:

区间dp问题
我们这么想,对于顶点i到j的最小权值和是多少?
我们在i和j中枚举k,i和j形成一个线段,加上k就可以组成一个三角形,此时剩余部分为i到k和k到j,三角形ijk的值我们可以算出,剩余部分相当于小区间,我们已经提前算出,所以取最小就是i到j的答案
在这里插入图片描述

我们用f[i][j]表示顶点i到顶点j的最小权值乘积和,
f[l][r]=min(f[l][r],f[l][k]+f[k][r]+a[l]*a[k]*a[r]);
本题写高精度或者用__int128

代码:

#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;
}

以上是关于Acwing1069. 凸多边形的划分的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1069: [SCOI2007]最大土地面积 凸包+旋转卡壳求最大四边形面积

bzoj1069最大土地面积

bzoj1069: [SCOI2007]最大土地面积

[BZOJ]1069 最大土地面积(SCOI2007)

bzoj1069: [SCOI2007]最大土地面积

BZOJ1069: [SCOI2007]最大土地面积