当前位置:   article > 正文

动态规划-凸多边形最优三角形(权值和)

最优三角形

参考b站讲解链接->凸多边形最优三角形

1.算法概述

  给定一个具有N个顶点的多边形,每个顶点都有一个权值。我们的目标是将该多边形划分为若干个不相交的凸三角形,并使这些凸三角形的权值和最小。

2.算法实现

   定义一个名为minScoreTriangulationPlan的函数来计算多边形的最小权值和。该函数采用分治的思想,具体实现如下:

  1. double minScoreTriangulationPlan(double a[], int l, int r)
  2. {
  3. if (r - l < 2) // 当点数小于3时,无法构成三角形,返回0
  4. {
  5. return 0;
  6. }
  7. if (r - l == 2) // 当点数等于3时,可以构成一个三角形,返回权值和
  8. {
  9. return a[l] + a[l + 1] + a[r];
  10. }
  11. else // 当点数大于3时,需要遍历求解最小权值和
  12. {
  13. double minScore;
  14. int biaoji = l + 1; // 记录权值和最小的点索引
  15. for (int i = l + 1; i < r; i++)
  16. {
  17. double left = minScoreTriangulationPlan(a, l, i); // 左边的权值和,递归调用得到
  18. double mid = a[l] + a[i] + a[r]; // 中间直接计算权值
  19. double right = minScoreTriangulationPlan(a, i, r); // 右边的权值和,递归调用得到
  20. double sum = left + mid + right; // 当前划分方式下的权值和
  21. if (i == l + 1)
  22. {
  23. minScore = sum; // 记录初始最小权值和
  24. }
  25. minScore = min(sum, minScore); // 更新最小权值和
  26. if (minScore == sum)
  27. {
  28. biaoji = i; // 更新最小权值和对应的点索引
  29. }
  30. }
  31. cout << "第" << l + 1 << "(" << a[l] << ")" << "区域到"
  32. << r + 1 << "(" << a[r] << ")" << "区域,"
  33. << "最小连点为" << biaoji + 1 << "(" << a[biaoji] << ")" << endl;
  34. return minScore; // 返回最小权值和
  35. }
  36. }

3.算法使用

  在主函数中,通过用户输入来获取多边形的点数和各个顶点的权值,并调用minScoreTriangulationPlan函数来计算最小权值和。最后,将结果输出给用户。

  1. int main()
  2. {
  3. cout << "请输入多边形的点数:" << endl;
  4. int N;
  5. cin >> N;
  6. double a[N];
  7. for (int i = 0; i < N; i++)
  8. {
  9. cout << "请输入第" << i + 1 << "点的权值:" << endl;
  10. cin >> a[i];
  11. }
  12. double minScore = minScoreTriangulationPlan(a, 0, N - 1);
  13. cout << "多边形构成凸三角形最小的权值和为:" << minScore << endl;
  14. return 0;
  15. }

4.算法解释

  首先,判断多边形的点数。如果点数小于3,即无法构成三角形,直接返回0。

   如果点数等于3,那么这三个点可以构成一个三角形,并返回它们的权值和。
   对于点数大于3的情况,通过循环遍历所有的划分方式,递归计算左右两侧的最小权值和,并计算当前划分下的权值和。同时,我们记录使得权值和最小的划分方式,并将其对应的点索引保存下来。

   最后,输出权值和最小的划分方式,并返回最小权值和。

5.运行结果

 

6.完整代码

  1. #include<iostream>
  2. #include<cmath>
  3. using namespace std;
  4. // 计算多边形分割后的最小权值和
  5. double minScoreTriangulationPlan(double a[], int l, int r)
  6. {
  7. // 当点数小于3,无法构成三角形,返回0
  8. if (r - l < 2)
  9. {
  10. return 0;
  11. }
  12. // 当点数等于3,可以构成一个三角形,返回权值和
  13. if (r - l == 2)
  14. {
  15. return a[l] + a[l + 1] + a[r];
  16. }
  17. // 当点数大于3,需要遍历求解最小权值和
  18. else
  19. {
  20. double minScore;
  21. int biaoji = l + 1; // 记录权值和最小的点索引
  22. for (int i = l + 1; i < r; i++)
  23. {
  24. double left = minScoreTriangulationPlan(a, l, i); // 左边的权值和,递归调用得到
  25. double mid = a[l] + a[i] + a[r]; // 中间直接计算权值
  26. double right = minScoreTriangulationPlan(a, i, r); // 右边的权值和,递归调用得到
  27. double sum = left + mid + right; // 当前划分方式下的权值和
  28. // 更新最小权值和
  29. if (i == l + 1)
  30. {
  31. minScore = sum;
  32. }
  33. minScore = min(sum, minScore);
  34. if (minScore == sum)
  35. {
  36. biaoji = i;
  37. }
  38. }
  39. cout << "第" << l + 1 << "(" << a[l] << ")" << "区域到"
  40. << r + 1 << "(" << a[r] << ")" << "区域,"
  41. << "最小连点为" << biaoji + 1 << "(" << a[biaoji] << ")" << endl;
  42. return minScore;
  43. }
  44. }
  45. int main()
  46. {
  47. cout << "请输入多边形的点数:" << endl;
  48. int N;
  49. cin >> N;
  50. double a[N];
  51. for (int i = 0; i < N; i++)
  52. {
  53. cout << "请输入第" << i + 1 << "点的权值:" << endl;
  54. cin >> a[i];
  55. }
  56. double minScore = minScoreTriangulationPlan(a, 0, N - 1);
  57. cout << "多边形构成凸三角形最小的权值和为:" << minScore << endl;
  58. return 0;
  59. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/670562
推荐阅读
相关标签
  

闽ICP备14008679号