Division of [interval DP] convex polygon

Posted by jamesjohnson88 on Fri, 18 Feb 2022 10:04:32 +0100

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.

  1. In the future, we must analyze the time complexity and variable types.
  2. Start with the original template idea, and then deform it.

Topics: Algorithm data structure