学习自https://www.jianshu.com/p/b97b0bb78b6c
一.问题分析:
将凸多边形内部划分成若干三角形,每一条线都带权
哪一种划法,让
三角形的权最小?
因其具有最优子结构:
所以,总问题的最优解=子问题的最优解+
一个三角形的权即
举例来说:当程序运行到i=0,j=5,k=3时:
设: 求解的是多边形{V0,V1,........Vn-1}
bestWeight[ i ] [ j ] =m 表示它的一个子多边形{Vi , Vi+1 , ... , Vj-1 , Vj}的最优解=m (所以最终解为bsetWeight[ 0 ][ n-1 ])
bestPoint[ i ] [ j ] = k 表示该子多边形出现最优解时,构成的三角形为{ Vi , Vk , Vj }.
当i==j时,子问题退化成了点 ; 当i+1=j时,子问题退化成了一条线.
此时要退出,并且bestWeight[ i ] [ j ] =0;bestPoint[ i ] [ j ] = -1
二.代码实现
const int N = 6;
vector<vector<int>> weight = {// 给出权函数。
{0, 2, 3, 1, 5, 6},
{2, 0, 3, 4, 8, 6},
{3, 3, 0, 10, 13, 7},
{1, 4, 10, 0, 12, 5},
{5, 8, 13, 12, 0, 3},
{6, 6, 7, 5, 3, 0} };
//记录最优权值
vector<int>tempWeight(N, 0);
vector<vector<int>>bestWeight(N, tempWeight); //bestWeight[i][j]=m表示多边形{Vi, ... , ... , ... , Vj}的最优解=m
//记录最优策略
vector<int>tempPoint(N,-1);
vector<vector<int>> bestPoint(N, tempPoint);// bestPoing[i][j]=k 表示 Vi、Vj 构成三角形第三个顶点 Vk 。
//计算三角权重之和
int getWeight(int i, int k, int j)
{
return weight[i][k] + weight[i][j] + weight[k][j];
}
//自底而上的DP算法, (组合子问题的解->父问题的解)
int TriSplit(int n)
{
//i==j时是点; j = i + 1时是边,此时的bestWeight[i][j]=0
//但无需赋值,数组已默认全为0
for (int scale = 2; scale < n; scale++)//遍历2~N-1条边的多边形
{
for (int i = 0; i < N - scale; i++)//例如,边数=2时,(V0,V1,V2)~(V3,V4,V5)
{
int j = i + scale; //多边形的Vj
int k = i + 1;
bestWeight[i][j] = bestWeight[i][k] + bestWeight[k][j] + getWeight(i, k, j);//记录第一个基准值
bestPoint[i][j] = k;
for (k = i + 2; k < j; k++)//( i < k < j )
{
int t = bestWeight[i][k] + bestWeight[k][j] + getWeight(i, k, j);
if (t < bestWeight[i][j])
{
bestWeight[i][j] = t;
bestPoint[i][j] = k;
}
}
}
}
return bestWeight[0][N - 1];//返回整体{V0~VN-1}的最优解
}
void TSPrint(int i, int j)
{
if (j == i + 1 || j == i)
{
return;
}
TSPrint(i, bestPoint[i][j]);
cout << "V" << i << " -- V" << bestPoint[i][j] << " -- V" << j << " = " << getWeight(i,bestPoint[i][j],j)<<endl;
TSPrint(bestPoint[i][j], j);
}
main()
cout << endl << "最优三角剖分的权值之和为:" << TriSplit(N) << endl << endl;
cout << "剖分结果为:" << endl;
TSPrint(0, N - 1);
三.几个疑惑
1.当规模=2时,需求解多边形{V0,V1,V2} , {V1,V2,V3} , {V2,V3,V4} , {V3,V4,V5},实际上是六边形的4/6个角
但没有取{V4,V5,V0} , {V5,V0,V1}这剩下的2个角
2.当规模变大时也是一样.不能取余吗?
来源:CSDN
作者:IronBull_Zhang
链接:https://blog.csdn.net/IronBull_Zhang/article/details/104214256