C++---interval DP/high-precision calculation---division of convex polygons (one algorithm per day 2023.4.27)

Note:
This question is an extended question of "Interval DP—Energy Necklace" , so you can understand that question first.
This question uses "high-precision multiplication" and "high-precision addition" . You can read these two articles for detailed explanations.

Question:
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 this 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 the sum of the vertex weight products of all triangles at least for how much.

Input Format
The first line contains the integer N, the number of vertices.
The second line 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.

The data range
N≤50,
the data guarantees that the weights of all vertices are less than 10^9

输入:
5
121 122 123 245 231
输出:
12214884
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

typedef long long LL;
const int N = 55;
int n, w[N];            //w[i]为第i个顶点的权值
vector<int> f[N][N];  //注意这是个三维数组(第三维是用来算高精度),f[l][r]为从l点到r点整个区域内的不相交的三角形的选法,属性为min(三角形权值之和)

//高精度加法
vector<int> add(vector<int> &A, vector<int> &B) {
    
    
    if (A.size() < B.size()) return add(B, A);
    vector<int> res;
    int t = 0;
    for (int i = 0; i<A.size(); i++) {
    
    
        t += A[i];
        if (i < B.size()) t += B[i];
        res.push_back(t % 10);
        t /= 10;
    }
    if (t) res.push_back(t);
    return res;
}

//高精度乘法
vector<int> multi(vector<int> &A, LL B) {
    
    
    vector<int> res;
    LL t = 0;
    for (int i = 0; i<A.size() || t; i++) {
    
    
        if (i < A.size()) t += (A[i] * B);
        res.push_back(t % 10);
        t /= 10;
    }
    while (res.size() > 1 && res.back() == 0) res.pop_back();
    return res;
}

//高精度比较 compare(A < B)?
bool cmp(vector<int> &A, vector<int> &B) {
    
    
    if (A.size() != B.size()) return A.size() < B.size();
    for (int i = A.size()-1; i>=0; i--) {
    
    
        if (A[i] != B[i]) {
    
    
            return A[i] < B[i];
        }
    }
    return true;
}

int main() {
    
    
    //读入
    cin >> n;
    for (int i = 1; i<=n; i++) cin >> w[i];

    //dp (区间长度len -> 左端点l -> 分界线k)
    for (int len = 3; len <= n; len++) {
    
    
        for (int l = 1; l+len-1 <= n; l++) {
    
    
            int r = l+len-1;
            for (int k = l+1; k<r; k++) {
    
    
                vector<int> new_value;
                new_value.push_back(1);     //初始化设为1,这样就能计算乘法了
                //w[l]*w[k]*w[r]
                new_value = multi(new_value, w[l]);
                new_value = multi(new_value, w[k]);
                new_value = multi(new_value, w[r]);
                //f[l][k] + f[k][r]
                new_value = add(new_value, f[l][k]);
                new_value = add(new_value, f[k][r]);
                //f[l][r] = min(f[l][r], new_value)
                if (f[l][r].empty() || cmp(new_value, f[l][r])) f[l][r] = new_value;
            }
        }
    }

    //f[1][n]为答案,注意存的是高精度,所以要倒着输出一下
    for (int i = f[1][n].size()-1; i>=0; i--) cout << f[1][n][i];
    return 0;
}

Idea:
let’s understand the topic first.
After selecting two points, the plan to form a triangle with the remaining points is n-2 (the picture of the colored lead guy): Please add a picture description
for any such triangle, you can use it To divide the interval (assuming that the triangle 1-4-6 is selected):
Please add a picture description
Then the left interval (1-2-3-4) and the right interval (4-5-6) do not interfere with each other, and
the left interval can be obtained The minimum value f[1][4]of and the minimum value of the interval f[4][6]on the right plus the current w[1]*w[4]*w[6]value is the answer to choose (1-4-6) this triangle.

Then dynamic programming, or the classic y-style dp method:
1. State representation
f[L][R] : the leftmost endpoint of the current area (polygon) is L, and the rightmost endpoint is R for all schemes, and
the attribute is Min (the sum of triangle weights) .
2. State calculation
With L and R as the base and the boundary point K as the apex:
the left interval + the current triangle weight + the right interval
f[l][r] = min(f[l][r], f[l][k] + f[k][r] + w[l]*w[k]*w[r])

If it is helpful, please give a free like~ Someone watching is the motivation to support me to write down!

Disclaimer:
The source of the algorithm idea is Mr. Y. For details, please refer to https://www.acwing.com/
This article is only used for learning records and exchanges

Guess you like

Origin blog.csdn.net/SRestia/article/details/130413265