【题意】题目链接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;
}