描述
给定凸多边形 P 各顶点坐标集 {v0,v1,…,vn−1},保证各顶点坐标依逆时针次序给出。定义由多边形的边和弦组成的三角形上的权函数 w(vivjvk)=∣vivj∣+∣vjvk∣+∣vkvi∣,相应于此权函数的最优三角剖分即为最小弦长三角剖分。
其中 ∣vivj∣ 是点 vi 到 vj 的欧氏距离。要求确定该凸多边形的三角剖分,使得该三角剖分所对应的权,即该三角剖分中诸三角形上权之和为最小。输出该最小值。
设 vi=(x1,y1),vj=(x2,y2),则 vi 和 vj 的欧氏距离 = (x1−x2)×(x1−x2)+(y1−y2)×(y1−y2)
输入描述
第一行为一个整数 n(3≤n≤100),表示凸多边形 P 的顶点数。
接下来有 n 行,每行由两个整数组成,表示顶点的欧氏坐标 x 和 y(0≤x,y≤1000),按照顺时针方向输入。
输出描述
一个非负数,表示凸多边形 P 的三角剖分中诸三角形上权值和的最小值,结果保留小数点后 3 位。
用例输入 1
4 0 0 0 1 1 1 1 0
用例输出 1
1.414
代码如下:
#include<iostream>
#include<math.h>
using namespace std;
int n;
double a[150],b[150];
double c[150][150]; //各顶点间剖分后的最小权值
int main(){
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i]>>b[i];
}
for(int i=3;i<=n;i++){ //剖分三角形的底边长度
for(int j=0;j<n-i+1;j++){ //剖分三角形的底边起点下标
int k=i+j-1; //剖分三角形的底边终点下标
c[j][k]=0x7fffffff; //初始化
for(int w=j+1;w<k;w++){
c[j][k]=min(c[j][k],c[j][w]+c[w][k]+(sqrt((a[j]-a[k])*(a[j]-a[k])+(b[j]-b[k])*(b[j]-b[k])))); //更新a[i][j]为当前剖分方式下的最小权值
}
}
}
printf("%.3lf\n",c[0][n-1]-sqrt((a[0]-a[n-1])*(a[0]-a[n-1])+(b[0]-b[n-1])*(b[0]-b[n-1])));
return 0;
}