Cod sursa(job #3237488)

Utilizator popescu_georgePopescu George popescu_george Data 9 iulie 2024 12:48:04
Problema Parantezare optima de matrici Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.58 kb
#include<fstream>
#include<algorithm>
#include<stack>
#include<map>
using namespace std;
ifstream in("podm.in");
ofstream out("podm.out");
const int N_MAX = 500;
int N, nrBridges = -1;
pair<int, int> Bridges[2 * N_MAX], w[N_MAX + 2];
map<pair<int, int>, int> Childs;
long long M[2 * N_MAX][N_MAX + 1];
void Mark_Bridges()
{
	rotate(w, min_element(w, w + N), w + N);
	for (int i = 0; i < N; ++i)
		w[i].second = i;
	w[N] = w[0];
	stack<int> S;
	for(int i = 1; i <= N; ++i) {
		S.push(i - 1);
		while (w[i] < w[S.top()]) {
			int t = S.top();
			S.pop();
			Bridges[++nrBridges].first = S.top(), Bridges[nrBridges].second = t;
			Bridges[++nrBridges].first = t, Bridges[nrBridges].second = (i == N ? 0 : i);
			Childs[make_pair(S.top(), (i == N ? 0 : i))] = nrBridges;
		}
	}
}
long long Partition()
{
	for (int ind = 0; ind <= nrBridges; ++ind) {
		int i = Bridges[ind].first, j = Bridges[ind].second;
		if (w[i] > w[j])
            swap(i, j);
		if (!Childs.count(Bridges[ind])) {
			M[ind][i] = 0;
			for (int k = 0; k < N; ++k)
				if (w[k] < w[i])
					M[ind][k] = 1LL * w[i].first * w[j].first * w[k].first;
		} else {
			int s = Childs[Bridges[ind]];
			M[ind][i] = M[s][i] + M[s - 1][i];
			for (int k = 0; k < N; ++k)
				if (w[k] < w[i])
					M[ind][k] = min(M[ind][i] + 1LL * w[i].first * w[j].first * w[k].first, M[s][k] + M[s - 1][k]);
		}
	}
	return M[Childs[make_pair(0, 0)]][0] + M[Childs[make_pair(0, 0)] - 1][0];
}
int main() {
	in >> N;
	++N;
	for (int i = 0; i < N; ++i)
		in >> w[i].first;
	Mark_Bridges();
	out << Partition();
	return 0;
}