Cod sursa(job #2258768)

Utilizator cosmin.pascaruPascaru Cosmin cosmin.pascaru Data 11 octombrie 2018 23:27:29
Problema Parantezare optima de matrici Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.63 kb
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <array>
#include <algorithm>
#include <vector>
#include <stack>
#include <set>
#include <assert.h>
#include <queue>
#include <chrono>
#include <memory>
#include <cstring>

using LL = long long;
using ULL = int long long;

const std::string _problemName = "podm";

#define USE_FILES

#ifdef USE_FILES

namespace std {
std::ifstream fin(_problemName + ".in");
std::ofstream fout(_problemName + ".out");
}

#define cin fin
#define cout fout
#endif

// optimum[i][j] = optimum number of multiplications to multiply matrices [i...j]
// optimum[i][i] = 0
// optimum[i][j] = min_(k = i+1, j-1)(optimum[i][k] + cost(i, k, j) + optimum[k][j])

using matrix = std::vector< std::vector<int64_t> >;

matrix squareMatrix(int size) {
    return std::vector< std::vector<int64_t> > (size, std::vector<int64_t>(size));
}

int64_t computeOptimum(const matrix& optimum, int left, int right, const std::vector<int>& dimensions) {
    
    auto lines = [&dimensions] (int matrixIdx) -> int {
        return dimensions[matrixIdx];
    };
    auto columns = [&dimensions] (int matrixIdx) -> int {
        return dimensions[matrixIdx + 1];
    };
    auto cost = [&] (int left, int mid, int right) -> int64_t {
        // the number of multiplications required for multiplying matrices with dimensions 
        // [left, left + 1], [mid, mid + 1] and [right, right + 1]
        return 1LL * lines(left) * columns(mid) * columns(right);
    };

    int64_t minimum = std::numeric_limits<int64_t>::max();

    for (int mid = left; mid < right; ++mid) {
        // split into [left, mid] and [mid + 1, right] and then add the cost of multiplying those matrices
        int64_t value = optimum[left][mid] + optimum[mid + 1][right] + cost(left, mid, right);
        if (minimum > value) {
            minimum = value;
        }
    }

    return minimum;
}

int64_t computeOptimalMultiplicationsCount(const std::vector<int>& dimensions) {
    int matricesCount = dimensions.size() - 1;
    matrix optimum = squareMatrix(matricesCount);

    // iterate by main diagonals
    for (int firstRight = 0; firstRight < matricesCount; ++firstRight) {
        for (int left = 0 ; left < matricesCount - firstRight; ++left) {
            int right = left + firstRight;
            optimum[left][right] = computeOptimum(optimum, left, right, dimensions);
        }
    }
    return optimum[0][matricesCount - 1];
}

int main() {

    int n;
    std::cin >> n;

    std::vector<int> dimensions(n + 1);

    for (int& it : dimensions) {
        std::cin >> it;
    }

    std::cout << computeOptimalMultiplicationsCount(dimensions);

    return 0;
}