区间DP凸多边形的划分
Posted Vincent_0000
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区间DP凸多边形的划分相关的知识,希望对你有一定的参考价值。
题目来源
题目描述
给定一个具有 N 个顶点的凸多边形,将顶点从 1 至 N 标号,每个顶点的权值都是一个正整数。
将这个凸多边形划分成 N−2 个互不相交的三角形,对于每个三角形,其三个顶点的权值相乘都可得到一个权值乘积,试求所有三角形的顶点权值乘积之和至少为多少。
输入格式
第一行包含整数 N,表示顶点数量。
第二行包含 N 个整数,依次为顶点 1 至顶点 N 的权值。
输出格式
输出仅一行,为所有三角形的顶点权值乘积之和的最小值。
数据范围
N≤50,
数据保证所有顶点的权值都小于
1
0
9
10^9
109
输入样例:
5
121 122 123 245 231
输出样例:
12214884
题目思路
- 分析题型
成环,在区间中挑点,数据范围不太大,求最小值
−
>
->
−>区间DP问题。
权值太大,需要使用高精度。
- DP分析
在多边形中需要挑选三个点,对于最基础的区间DP模板,刚好有三个点,且都是变化的,那么就直接以他们做为集合的划分。
结合大数模拟即可得出答案。
- 边界值
先要将我们的数组初始化为一个很大的值。
然后进行运算,并不会影响结果的,因为是一段一段遍历过来的,所以到遍历一段的时候,长度比他小的那一段已经遍历过了。
- 目标
f [ 1 ] [ n ] f[1][n] f[1][n]
AC代码
#include<bits/stdc++.h>
using namespace std;
#define _for(i, a, b) for (int i = (a); i < (b); ++i)
#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define For(i, a, b) for (int i = (a); i >= (b); --i)
#define debug(a) cout << #a << " = " << a << ENDL
#define ENDL "\\n"
#define x first
#define y second
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
const int N = 50 + 5, M = 35;
ll f[N][N][M], w[N];
void mul(ll a[], ll x) {
ll t = 0;
_for(i, 0, M) {
t += a[i] * x;
a[i] = t % 10;
t /= 10;
}
}
void add(ll* a, ll* b) {
ll t = 0;
_for(i, 0, M) {
t += a[i] + b[i];
a[i] = t % 10;
t /= 10;
}
}
bool cmp(ll* a, ll* b) {
For(i, M - 1, 0) if (a[i] > b[i]) return true;
else if (a[i] < b[i]) return false;
return false;
}
void Print(ll* a) {
int r = M;
while (!a[r] && r) --r;
while (~r) cout << a[r--];
cout << ENDL;
}
int main() {
#ifdef LOCAL
freopen("data.in", "r", stdin);
#endif
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int n;
cin >> n;
_rep(i, 1, n) cin >> w[i];
_rep(len, 3, n) _rep(l, 1, n - len + 1) {
int r = l + len - 1;
f[l][r][M - 1] = 1;
_for(k, l + 1, r) {
ll tmp[M] = { 1 };
mul(tmp, w[l]);
mul(tmp, w[r]);
mul(tmp, w[k]);
add(tmp, f[l][k]);
add(tmp, f[k][r]);
if (cmp(f[l][r], tmp)) memcpy(f[l][r], tmp, sizeof tmp);
}
}
Print(f[1][n]);
return 0;
}
反思
这题做之前没有分析出这是一个高精度问题,想着三个数相乘不会爆long long,但是自己没有想到的是他们还要相加。
这个不是错这个题目的根本原因,先分析出来了这是 区间DP,确定区间之后,我却想着再在区间中找两个点,,没有考虑到两边的端点都可以作为动态转移方程的关键变量。
- 以后做题一定要分析到时间复杂度以及变量类型。
- 先以原始模板思路开始想,然后再进行变形。
以上是关于区间DP凸多边形的划分的主要内容,如果未能解决你的问题,请参考以下文章