Acwing1069. 凸多边形的划分
Posted Jozky86
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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. 凸多边形的划分的主要内容,如果未能解决你的问题,请参考以下文章