[区间DP] 凸边形三角剖分(子问题的表达)

题目

这里写图片描述

思路

本题极其类似于最优矩阵链乘,同样是最优子结构,同样是二分区间DP,唯一的不同在于本题难以简洁地表达子问题。
为什么呢?类似于最优矩阵链乘。
A1A2A3A4A5A6 A 1 A 2 A 3 A 4 A 5 A 6 —- >>>> (A1A2)(A3A4A5A6) ( A 1 A 2 ) ( A 3 A 4 A 5 A 6 )
(1,6)>>>>(1,2)(3,6) ( 1 , 6 ) − − − − >>>> ( 1 , 2 ) ( 3 , 6 )
不管怎么分,子问题都可以简洁地用一个区间来表达。
但是三角剖分,你剖分的这一刀可以是在任意的两个点,这就造成了在如下情况:
这里写图片描述
就很难用一个区间就能表示的了。
因此有必要把决策的顺序规范化,使得在规范的决策顺序下,任意状态都能用区间表示。


1.状态定义:d(i,j),由点表示的子多边形i,i+1,…,j-1,j的最优值。
2.边界:d(i,i+1)=0
3.答案:d(1,n)
4.状态转移方程:

d(i,j)=max{d(i,k)+d(k,j)+w(i,j,k)|i<k<j} d ( i , j ) = m a x { d ( i , k ) + d ( k , j ) + w ( i , j , k ) | i < k < j }

这里写图片描述
5.复杂度: O(n3) O ( n 3 )

代码

没有任何OJ上有本题的模板题,也没有找到任何的样例数据。。。所以只能凭感觉反映一下思路即可,下面的代码有99%的可能性有bug

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define _for(i,a,b) for(int i = (a); i<(b); i++)
#define _rep(i,a,b) for(int i = (a); i<=(b); i++)
using namespace std;

const int maxn = 100 + 10;
int n, w[maxn][maxn][maxn], d[maxn][maxn];

int main() {
    scanf("%d", &n);
    // 三角形权值可以是周长,面积等,此处假设题目输入
    _rep(i, 1, n)
        _rep(j, 1, n)
            _rep(k, 1, n)
                scanf("%d", &w[i][j][k]);

    _rep(i, 1, n - 1) d[i][i + 1] = 0;

    int j;
    _rep(l,2,n)
        _rep(i, 1, n) {
            j = i + l;
            if (j > n) continue;
            _rep(k, i + 1, j - 1)
                d[i][j] = max(d[i][j], d[i][k] + d[k][j] + w[i][j][k]);
        }

    printf("%d\n", d[1][n]);

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值