Topic source
Click me to enter the ACwing official website to submit
Title Description
Given a convex polygon with n vertices, label the vertices from 1 to N, and the weight of each vertex is a positive integer.
Divide the convex polygon into N − 2 disjoint triangles. For each triangle, the weights of its three vertices can be multiplied to obtain a weight product. Try to find out the sum of the vertex weight products of all triangles.
Input format
The first line contains the integer N, which represents the number of vertices.
The second row contains N integers, which are the weights from vertex 1 to vertex N in turn.
Output format
Output only one line, which is the minimum value of the sum of the vertex weight products of all triangles.
Data range
Nā¤50,
Ensure that the weight of all data is less than the vertex
1
0
9
10^9
109
Input sample:
5
121 122 123 245 231
Output example:
12214884
Topic idea
- Analysis question type
Form a ring, select points in the interval, the data range is not too large, and find the minimum value
ā
>
->
− > interval DP problem.
The weight is too large and high precision is required.
- DP analysis
Three points need to be selected in the polygon. For the most basic interval DP template, there are exactly three points, and they are all changing, so they are directly used as the division of the set.
Combined with large number simulation, the answer can be obtained.
- Boundary value
First, initialize our array to a large value.
Then the operation will not affect the result, because it is traversed section by section, so when traversing a section, the section with a length smaller than him has been traversed.
- target
f [ 1 ] [ n ] f[1][n] f[1][n]
AC code
#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; }
reflect
I didn't analyze this problem before I did it. It was a high-precision problem. I thought that multiplying three numbers would not explode long long, but what I didn't think was that they had to add.
This is not the root cause of the problem. First, it is analyzed that this is interval DP. After determining the interval, I want to find two points in the interval, without considering that the endpoints on both sides can be used as the key variables of the dynamic transfer equation.
- In the future, we must analyze the time complexity and variable types.
- Start with the original template idea, and then deform it.