Cod sursa(job #1451288)

Utilizator GilgodRobert B Gilgod Data 16 iunie 2015 18:25:07
Problema Parantezare optima de matrici Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.28 kb
#include <iostream>
#include <cstring>

#define INF 0x3f3f3f3f

const int NMAX = 501;
const char IN[] = "podm.in", OUT[] = "podm.out";

using namespace std;

long long M[NMAX][NMAX], S[NMAX][NMAX];
long long N;
long long P[NMAX];

inline void read_data() {
	freopen(IN, "r", stdin);
	scanf("%d", &N);
	for (int i = 0; i <= N; ++i) {
		scanf("%d", &P[i]);
	}
	fclose(stdin);
}

inline long long parantezare_optima() {
	//initializari pesimiste
	memset(M, INF, sizeof(M));
	//caz de baza A[i,i] = 0
	for (int i = 0; i <= N; ++i) M[i][i] = S[i][i] = 0;
	//lanturi de 2..n-1
	for (int l = 2; l <= N; ++l) {
		//inceputul lantului
		for (int i = 1; i <= N - l + 1; ++i) {
			//Ai * ... * Aj
			int j = i + l - 1;
			for (int k = i; k < j; ++k) {
				//(Ai*...*Ak) * (Ak+1 * ... * Aj)
				//k de la i la j-1(toate posibilitatie)
				//Ai = (pi-1,pi) Ak = (pk-1,pk) => Ai*..*Ak = (pi-1, pk)
				//Ak+1 = (pk, pk+1) Aj = (pj-1,pj) => Ak+1*..*Aj = (pk, pj)
				long long q = M[i][k] + M[k + 1][j] + P[i - 1] * P[k] * P[j];
				if (M[i][j] > q) {
					M[i][j] = q;
					S[i][j] = k;
				}
			}
		}
	}
	printf("Parantezare optima: %lld\n", M[1][N]);
	return M[1][N];
}

int main() {
	read_data();
	fprintf(fopen(OUT, "w"), "%lld\n", parantezare_optima());
	return 0;
}