凸多边形的划分 区间dp

Posted 行码棋

tags:

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

原题链接

状态表示: f [ i ] [ j ] [ k ] f[i][j][k] f[i][j][k]表示选择以第i个点开头,以第j个点结尾的围成凸多边形的最小值,k是为了写高精度对第三维做的扩充,表示数的每一位。
转移方程: f [ i ] [ j ] = m i n ( f [ i ] [ j ] , f [ i ] [ k ] + f [ k ] [ j ] + w [ i ] ∗ w [ j ] ∗ w [ k ] ) f[i][j] = min(f[i][j], f[i][k] + f[k][j] + w[i] * w[j] * w[k]) f[i][j]=min(f[i][j],f[i][k]+f[k][j]+w[i]w[j]w[k])
因为数的范围太大,需要使用高精度写,故对状态增加一维

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N = 105,M = 34,inf = 0x3f3f3f3f;

int a[N];
ll f[N][N][M];
int n;
//大数相乘
void mul(ll a[],ll b)
{
	static ll c[M];
	memset(c,0,sizeof c);
	ll t = 0;
	for(int i=0;i<M;i++)
	{
		t += a[i] * b;
		c[i] = t%10;
		t /= 10;
	}
	memcpy(a,c,sizeof c);
}
//大数相加
void add(ll a[],ll b[])
{
	static ll c[M];
	memset(c,0,sizeof c);
	int t = 0;
	for(int i=0;i<M;i++)
	{
		t += a[i]+b[i];
		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 p = M-1;
	while(p>=0 && !a[p]) p--;
	while(p>=0) cout<<a[p--];
	cout<<'\\n';
}
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	
	ll temp[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;
			for(int k=l+1;k<r;k++)
			{
				memset(temp,0,sizeof temp);
				temp[0] = a[l];
				mul(temp,a[k]);
				mul(temp,a[r]);
				add(temp,f[l][k]);
				add(temp,f[k][r]);
				if(cmp(temp,f[l][r])<0)
					memcpy(f[l][r],temp,sizeof temp);
			}
		}
	}
	print(f[1][n]);
	return 0;
}

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

凸多边形的划分 区间dp

区间dp

区间DP之凸多边形的三角剖分

Acwing1069. 凸多边形的划分

2/1 dp+区间dp+catalan数+Cayley公式

ZOJ 3537 Cake 求凸包 区间DP