凸多边形最优三角剖分——动态规划

来源:互联网 发布:中国财团知乎 编辑:程序博客网 时间:2024/05/01 20:10

解答:题目中顶点坐标编号从1开始,为了方便编程,将顶点从0开始,顶点的编号变为0到7。定义t[i][j],0=<i<j<n为凸多边形{Vi,Vi,…Vj}的最优三角剖分所对应的权函数值,退化的两点多边形{Vi,Vi+1}的权值为0。要计算凸n边形的最优权值为t[0][n-1]。

由于退化的两点多边形{Vi,Vi+1}的权值为0,t[i][i]=0。最优子结构的性质,t[i][j]的值是t[i][k]的值加上t[k][j]的值,再加上三角形ViVkVj的权值,其中,i<k<=j-1。K的位置有j-i-1个。因此可以再这j-i-1个未知中选出使t[i][j]值达到最小的位置,递归式为: t[i][j]=0 (j-i<=1)

t[i][j]=t[i][k]+t[k][j]+w(i,k,j) (j-i>=2)

算法的时间复杂度为O(n3)!



程序代码如下:

#include<cstdlib>#include<iostream>#include<cstdio>#include<cmath>#include<set>#include<cstring>#include <algorithm>#define LL long long#define inf 0x7fffffff#define E 1e-9#define M 100#define N 105using namespace std;int n,k,h,m;int graph[8][8]={0, 14, 25, 27, 10, 11, 24, 16,14, 0, 18, 15, 27, 28, 16, 14,25, 18, 0, 19, 14, 19, 16, 10,27, 15, 19, 0, 22, 23, 15, 14,10, 27, 14, 22, 0, 14, 13, 20,11, 28, 19, 23, 14, 0, 15, 18,24, 16, 16, 15, 13, 15, 0, 27,16, 14, 10, 14, 20, 18, 27, 0};int t[N][N],s[N][N];int w(int i,int j,int k){    return graph[i][j]+graph[j][k]+graph[i][k];}void printv(int v,int u)//输出添加的边!{    if(u-v<=2)    return ;    if(s[v][u]-v>=2)    {        printf("%d-%d\n",v,s[v][u]);        printv(v,s[v][u]);    }    if(u-s[v][u]>=2)    {        printf("%d-%d\n",s[v][u],u);        printv(s[v][u],u);    }}void print2(int ma[][N],int n,int m){     for (int i=0; i<=n ; i++ )        {                printf("%3d",ma[i][0]);            for (int j=1; j<=m ; j++)                printf(" %3d",ma[i][j]);            cout<<endl;        }}int main(){//#ifndef ONLINE_JUDGE//    freopen("ex.in","r",stdin);//#endif    n=8;    int j;    for(int r=2;r<=n-1;r++)    {        for(int i=0;i<n-r;i++)//到n-r就行,        {            j=i+r;            t[i][j]=t[i][i+1]+t[i+1][j]+w(i,i+1,j);            s[i][j]=i+1;            for(k=i+2;k<j;k++)            {                int u=t[i][k]+t[k][j]+w(i,k,j);                if(u<t[i][j])                {                    s[i][j]=k;                    t[i][j]=u;                }            }        }    }//    print2(t,n-1,n-1);    printf("%d\n",t[0][n-1]);//输出最优剖分总权值    printv(0,n-1);;//剖分时添加的线段    return 0;}