Cod sursa(job #3191771)

Utilizator RatebaSerbanescu Andrei Victor Rateba Data 10 ianuarie 2024 17:09:07
Problema Parantezare optima de matrici Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.23 kb
#include <fstream>
#include <climits>

using namespace std;

ifstream fin("podm.in");
ofstream fout("podm.out");

const int MAX_N = 502;
long long dp[MAX_N][MAX_N];
long long dims[MAX_N];

const long long INF = LONG_MAX;

int main() 
{

    int n;

    fin >> n;
    for (int i = 0; i <= n; i++) {
        fin >> dims[i];
    }

    // len este numărul matricelor în lanțul de înmulțire
    // i.e. * dacă len == 2, atunci interiorul for-ului calculează
    //        nr minim de înmulțiri scalare pt (A1 x A2), (A2 x A3), (A3 x A4)..
    //      * dacă len == 3, atunci interiorul for-ului calculează
    //        nr minim de înmulțiri scalare pt (A1 x A2 x A3), (A2 x A3 x A4)...
    for (int len = 2; len <= n; len++) {
        
        // i-ul este începutul lanțului de lungime len
        for (int i = 1; i <= n - len + 1; i++) {

            // j-ul este capătul lanțului de lungime len
            int j = i + len - 1;

            // de aici încolo calculăm nr min de înmulțiri scalare
            // pentru lanțul de matrice A(i) x A(i + 1) x ... x A(j)

            // ex. * dacă len == 2, i == 2
            //       atunci j == 4
            //       adică verificăm nr minim de înmulțiri scalare
            //       pt. lanțul A2 X A3 X A4



            // căutăm rezultatul următoarei formule de recurență
            // dp[i][j] = min(dp[i][k] + dp[k + 1][j] + dims[i - 1] * dims[k] * dims[j])
            // oricare ar fi k, a.î. i <= k < j

            dp[i][j] = LONG_MAX;
            for (int k = i; k < j; k++) {
                long long q = dp[i][k] + dp[k + 1][j] + dims[i - 1] * dims[k] * dims[j];
            
                dp[i][j] = min(dp[i][j], q);
            }

            // dp[i][j] este acum actualizat conform formulei de recurență de mai sus
            // am aflat nr minim de înmulțiri scalare pentru lanțul 
            // A(i) x A(i + 1) x ... A(j)
        }
    }

    // for (int i = 1; i <= n; i++) {
    //     for (int j = 1; j <= n; j++) {
    //         fout << setw(5) << dp[i][j] << ' ';
    //     }
    //     fout << endl;
    // }


    // dp[1][n] reprezintă numărul minim de înmulțiri scalare
    // pentru tot lanțul A1 x A2 x ... A(n)
    fout << dp[1][n];

    return 0;
}