凸n边形的三角形划分

来源:互联网 发布:大数据中学生阅读答案 编辑:程序博客网 时间:2024/05/20 01:09

问题:给定凸n边形P={1,2...,n},每一个顶点i带一个权数r(i)(i=1,2,...,n)。要求在该凸边形的顶点间连n-3条互不相交的连线,把凸边形分成n-2个三角形,每一个三角形的值为其他三个顶点权数之和。

解决过程:

(1)建立递推关系:

   设m(i,j)是求多边形MiMi+1...Mj划分的最小值,则有递推关系:

    m(i,i+2)=r(i)r(i+1)r(i+2)(j=i+2时,即三角形MiMi+1Mi+2)

    m(i,j)=min(m(i,k)+m(k,j)+r(i)r(k)r(j)(i<k<j)

   初始(边界)条件为m(i,i+1)=0(不构成三角形)

   显然,m(1,n)为最优值。

(2)求最优值的递推结构:

   当i<k<j且要求m(i,j)时,要用到m(i,k)和m(k,j)。为此,设置以下循环:

   for(d=2;d<=n-1;d++)

   for(i=1;i<=n-d;i++)

        j=i+d;

   这样,可按d从2开始递增取值,先得m(i,k)与m(k,j),为比较进而求m(i,j)提供可能。

(3)构造最优解

   设置s(i,j),在递推赋值时记录最优划分点k。注意到分划线分布为二叉结构,应用s(i,j)定义实现最优解的递归函数        f(a,b):

    a:设置c=s(a,b)记录参数a和b的最优分化点。

    b:若c>a+1,则输出a~c;

    c:若c<b-1,则输出c~b;

    d:然后调用下一层递归函数f(a,c)和f(c,b)。

   

#include<stdio.h>int p,s[100][100];main(){int d,n,i,j,k,r[100];long t,m[100][100];void f(int x,int y);printf(" 请输入n:");scanf("%d",&n);printf(" 凸%d边形从第一点开始,依次输入各点权数:\n",n);for(i=1;i<=n;i++){printf(" 请输入第%d个顶点的权数:",i);scanf("%d",&r[i]);}for(i=1;i<=n-1;i++) m[i][i+1]=0;for(d=2;d<=n-1;d++)for(i=1;i<=n-d;i++){j=i+d;m[i][j]=100000000;for(k=i+1;k<j;k++){t=m[i][k]+m[k][j]+r[i]*r[k]*r[j];if(t<m[i][j]){m[i][j]=t;s[i][j]=k;}}}p=0;printf("\n 最优%d条划分线分别为:\n",n-3);f(1,n);printf("\n 凸%d边形的三角形划分最小值为:%ld \n",n,m[1][n]);}
#include<stdio.h>void f(int a,int b){int c;if(b>a+1){c=s[a][b];if(c>a+1){p++;printf("  %2d--%2d;",a,c);if(p%6==0) printf("\n");}if(c<b-1){p++;printf("  %2d--%2d;",c,b);if(p%6==0) printf("\n");}f(a,c);f(c,b);}return;}


1 0
原创粉丝点击