zoukankan      html  css  js  c++  java
  • 区间DP之凸多边形的三角剖分

    题目

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

    输入

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

    输出

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

    样例

    样例输入

    5
    121 122 123 245 231

    样例输出

    12214884

    思路

    我们可以假设某个三角形在最优解的情况下,那么在遍历长度的情况下,枚举左端点,从而推出右端点,进而枚举断电,将整个凸多边形分成三部分,即f[i][j]=min(f[i][j],f[i][k]+f[k][j]+a[k]a[i]a[j]),从而求出最小价值(需要注意的是当发f[i][j]==0时,应当直接取后者值)

    代码

    
    
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=50+5;
    int n;
    ll a[maxn],f[maxn][maxn];
    int main(){
    	//freopen("1.in","r",stdin);
    	scanf("%d",&n);
    	for(int i=1;i<=n;++i)scanf("%lld
    ",&a[i]);
    	for(int i=1;i+2<=n;++i)f[i][i+2]=a[i]*a[i+1]*a[i+2];
    	for(int d=3;d<=n;++d){
    		for(int i=1;i+d-1<=n;++i){
    			int j=i+d-1;
    			for(int k=i+1;k<j;++k){
    				if(f[i][j])f[i][j]=min(f[i][j],f[i][k]+f[k][j]+a[k]*a[i]*a[j]);
    				else f[i][j]=f[i][k]+f[k][j]+a[k]*a[i]*a[j];
    			}
    		}
    	}
    	printf("%lld
    ",f[1][n]);
    	return 0;
    }
    
  • 相关阅读:
    二 、异常
    Java的基本概念
    Oracle case when
    oracle exists
    一 、前言
    location
    HTTP1.1初识
    数学学习笔记(持续更新中)
    [NOIP2017 提高组] 列队 题解
    [NOI2019] 回家路线 题解
  • 原文地址:https://www.cnblogs.com/soda-ma/p/13184285.html
Copyright © 2011-2022 走看看