您的位置:首页 > 其它

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

2012-09-19 17:29 232 查看
解答:题目中顶点坐标编号从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 105
using 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

,s

;
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[]
,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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: