区间DP——最优三角剖分

问题引入

给出一个n各顶点的凸多边形,有很多种方法可以对它进行三角剖分,即用n-3条互不相交的对角线把凸多边形分成n-2个三角形。为每个三角形规定一个权函数 w ( i , j , k ) w(i,j,k) w(i,j,k),求让所有三角形权值和最大的方案

状态转移

如果允许自由切割,那么多边形的顶点在原多边形中可以随意选取,很难定义成简洁的状态,无法找到递推的联系。如图选取了BCEG,这样的状态无法表示,因此我们需要将决策规范化

在这里插入图片描述

定义 d ( i , j ) d(i,j) d(i,j)为子多边形 i , i + 1 , . . . , j − 1 , j i,i+1,...,j-1,j i,i+1,...,j1,j的最优值,则边 i − j i-j ij的最优解一定含有点 i i i j j j,而这样的切割方法保证了每次切出来的多边形组成的点的编号都是连续的,于是我们就可以用两个元素表示一个多边形的状态

即状态转移方程为:

d ( i , j )   =   m a x ( d ( i , j ) , d ( i , k ) + d ( k , j ) + w ( i , j , k ) ) {d(i,j)~=~max(d(i,j),d(i,k)+d(k,j)+w(i,j,k))} d(i,j) = max(d(i,j),d(i,k)+d(k,j)+w(i,j,k)) i < k < j i<k<j i<k<j

边界 d ( i , i + 1 ) = 0 d(i,i+1)=0 d(i,i+1)=0,则该问题的解为 d ( 0 , n − 1 ) d(0,n-1) d(0,n1)

时间复杂度 O ( n 3 ) O(n^3) O(n3)

特殊情况

如果给出的多边形不一定是凸多边形,那么需要注意选取了 i , j , k i,j,k i,j,k三个点后,如果 i − k i-k ik j − k j-k jk两个对角线的任意一条与其他边相交,那么这个点就不能选,如何判断:

选定一个 k k k的时候,只需要看 i , j , k i,j,k i,j,k三点组成的三角形内部是否有点,如果有,那么必然会相交。如果一个点在三角形内部,那么将它与三角形三个顶点连线一定可以把三角形切分成3个三角形,且3个三角形面积之和就是这个大三角形的面积,根据面积作差来检验

const double eps=?;
const int maxn=?;

struct Point{
	//...
}p[maxn];

inline int dcmp(double d){
	if(fabs(d)<eps) return 0;
	return d>0?1:-1;
}

double area(int a,int b,int c){  //Point为计算几何中的点表示
    Point x=p[b]-p[a],y=p[c]-p[a];
    double s=(x^y)/2.0;
    return fabs(s);
}

bool check(int a,int b,int c){
    for(int i=0;i<n;i++){
        if(i==a || i==b || i==c) continue;
        double s=area(a,b,i)+area(a,c,i)+area(b,c,i)-area(a,b,c);
        if(dcmp(s)==0) return 0;
    }
    return 1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值