凸多边形的划分

题目描述

给定一具有N个顶点(从1到N编号)的凸多边形,每个顶点的权均已知。问如何把这个凸多边形划分成N-2个互不相交的三角形,使得这些三角形顶点的权的乘积之和最小?

输入输出格式

输入格式:

第一行 顶点数N(N<50)。 第二行 N个顶点(从1到N)的权值,权值为小于32768的整数。

输出格式:

一行,为各三角形顶点的权的乘积之和最小值。

输入输出样例

输入样例#1: 
5 
121 122 123 245 231
输出样例#1: 
12214884






思路:

设dp(i,j)表示i到j这一段连续的n边形划分成两部分后最小乘积

暴力枚举i到j之间顶点k

转移方程:dp[i][j]=min(dp[i][j],(dp[i][k]+dp[k][j]+a[i]*a[j]*a[k]))

具体思路可以参考别的博客

说几个我犯的智障错误

a数组开成int后面数据类型转换出了点小问题;忘记三角形三个顶点不能重合;dp数组忘记初始化然后魔怔般疯狂输出0

这种。


以下代码

#include 
#include 
#include 
#include 
#define ll long long

using namespace std;

int n;
ll a[100];
ll dp[100][100];

int main()
{
	memset(dp,0x3f,sizeof(dp));
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%lld",&a[i]);
	for(int i=n;i>=1;i--)
	{
		for(int j=i+1;j<=n;j++)
		{
			if(j-i==1)//容不下一个三角形(参见上述错误。)
				dp[i][j]=0;
			else if(j-i==2)
                dp[i][j]=a[i]*a[i+1]*a[i+2];//因为此时i和j中间只剩一个顶点了所以直接计算即可
            else
            	for(int k=i+1;k<=j-1;k++)
            	{
            		dp[i][j]=min(dp[i][j],(dp[i][k]+dp[k][j]+a[i]*a[j]*a[k]));
				}
		}
	}
	printf("%lld",dp[1][n]);
	return 0;
}

你可能感兴趣的:(凸多边形的划分)