二刷提高课,题解目录在这里— 提高课的题解目录
由于凸边形任意一条边都会用到,任意一条边都会在一个三角形内部
所以说不会存在断边用不到的地方,虽然看着像环其实是链式
并且要求互相独立,所以这里区间DP枚举以LR为边的三角形顶点即可
但是此题需要用高精度
为什么?
题目给的顶点权值最多1e9三个便是1e27很明显会爆ll,故需要用高精度
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=55,M=35;
ll f[N][N][M];
int n;
ll w[N];
void add(ll a[],ll w[])
{
static ll c[M];
memset(c,0,sizeof c);
for(int i=0,t=0;i<M;i++)
{
t+=a[i]+w[i];
c[i]=t%10;
t/=10;
}
memcpy(a,c,sizeof c);
}
void mul(ll a[],ll w)
{
static ll c[M];
memset(c,0,sizeof c);
ll t=0;
for(int i=0;i<M;i++)
{
t+=a[i]*w;
c[i]=t%10;
t/=10;
}
memcpy(a,c,sizeof c);
}
int cmp(ll a[],ll b[])
{
for(int i=M-1;i>=0;i--)
{
if(a[i]>b[i])return 1;
else if(a[i]<b[i])return -1;
}
return 0;
}
void print(ll a[])
{
int u=M-1;
while(u&&!a[u])u--;
while(u>=0)cout<<a[u--];
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)cin>>w[i];
ll tmp[M];
for(int len=3;len<=n;len++)
{
for(int l=1;l+len-1<=n;l++)
{
int r=l+len-1;
//这里求的最小值所以需要先赋值正无穷
f[l][r][M-1]=1;//最高位取1即使正无穷
for(int k=l+1;k<r;k++)
{
memset(tmp,0,sizeof tmp);
tmp[0]=w[l];
mul(tmp,w[k]);//这个时候会爆int,故用ll
mul(tmp,w[r]);
add(tmp,f[l][k]);
add(tmp,f[k][r]);
if(cmp(f[l][r],tmp)>0)memcpy(f[l][r],tmp,sizeof tmp);
}
}
}
print(f[1][n]);
return 0;
}