SMU 1106 - 凸多边形的最优三角剖分问题(区间DP)

【题意】题目链接http://218.5.241.13:8060/oj/showProblem.jsp?pid=1106 中文题

【分析】经典的最优三角剖分,这题的权值函数是三角形中弦长的平方和,此题数据很弱最多只有5个顶点;如果有错,欢迎指正

我再来加两组数据,具体分析看代码注释

INPUT

6
0 0
0 1
1 2
3 2
4 1
3 0
5
0 0
0 1
1 2
3 2
3 0
4
0 0
0 1
2 1
3 0

OUTPUT

22

13

5

【AC代码】 0ms

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXN 100
#define INF 0x3f3f3f3f
struct NODE{//记录每个顶点的坐标
    int x, y;
}p[MAXN];
int dp[MAXN][MAXN], n;
//dp[i][j]表示凸多边形(i~j+1)的最小权值总和

bool ok(int a, int b)//判断边ab是否为弦
{
    if ((a+1)%n == b || (a-1+n)%n == b)
        return false;
    return true;
}
int ss(int a, int b)//计算弦长的平方
{
    return (p[a].x-p[b].x)*(p[a].x-p[b].x)+(p[a].y-p[b].y)*(p[a].y-p[b].y);
}
int wei(int a, int b, int c)//计算三角形abc中的弦长的平方和
{
    int ans = 0;
    if (ok(a,b))
        ans +=  ss(a,b);
    if (ok(a,c))
        ans +=  ss(a,c);
    if (ok(b,c))
        ans += ss(b,c);
    return ans;
}
int dfs(int i, int j)
{
    if (-1 != dp[i][j])//记忆化
        return dp[i][j];
    if (j-i <= 1)//顶点少于3个的话费用为0
        return dp[i][j] = 0;
    //枚举k点,用三角形ikj把当前多边形划分成多边形(i~k)和(k~j)两个部分再加上当前三角形的费用
    int ans = INF;
    for (int k = i+1; k < j; k++)
        ans = min (ans, dfs(i,k-1)+dfs(k,j-1)+wei(i,k,j));
    return dp[i][j] = ans;
}
int main ()
{
    #ifdef SHY
        freopen("e:\\1.txt", "r", stdin);
    #endif
    while(~scanf ("%d%*c", &n))
    {
        memset(dp,-1,sizeof(dp));
        for (int i = 0; i < n; i++)
            scanf ("%d %d%*c", &p[i].x, &p[i].y);
        printf ("%d\n", dfs(0,n-1));
    }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值