Cod sursa(job #3285148)

Utilizator raulthestormIlie Raul Ionut raulthestorm Data 12 martie 2025 16:09:21
Problema Parantezare optima de matrici Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.65 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <limits>

using namespace std;
const auto INF = numeric_limits<unsigned long long>::max();

ifstream f("podm.in");
ofstream g("podm.out");

unsigned long long solve_podm(int n, const vector<int> &d)
{
    /// dp[i][j] = nr minim de inmultiri pt a calcula M_i * M_i+1 *..* M_j
    vector<vector<unsigned long long>> dp(n + 1, vector<unsigned long long> (n + 1, INF));
    //
    /// Cazul de baza 1: nu avem ce inmulti
    for(int i = 1; i <= n; i++)
        dp[i][i] = 0ULL;
    //
    /// Cazul de baza 2: matrice d[i - 1] x d[i] inmultitt cu matrice d[i] x d[i + 1]
    /// (matrice pe pozitii consecutive)
    for(int i = 1; i < n; i++)
        dp[i][i + 1] = 1ULL * d[i - 1] * d[i] * d[i + 1];
    //
    /// Cazul general:
    /// dp[i][j] = min(dp[i][k] + dp[k + 1][j] + d[i - 1] * d[k] * d[j]), k = i : j - 1
    for(int len = 2; len <= n; ++len)
    {
        for(int i = 1; i + len - 1 <= n; ++i) ///fixam capatul din stanga
        {
            int j = i + len - 1;    ///capatul din dreapta se deduce
            //
            /// Iteram prin indicii dintre capete, spargand sirul de inmultiri in doua
            for(int k = i; k < j; ++k)
            {
                unsigned long long cost = dp[i][k] + dp[k + 1][j] + 1ULL * d[i - 1] * d[k] * d[j];
                dp[i][j] = min(dp[i][j], cost);
            }
        }
    }
    //
    return dp[1][n];
}

int main()
{
    int n;
    f >> n;
    vector<int> d(n + 1);
    for(int i = 0; i <= n; i++)
        f >> d[i];
    g << solve_podm(n, d);
    f.close();
    g.close();
    return 0;
}