Pagini recente » Cod sursa (job #598971) | Cod sursa (job #1548747) | foxi_004 | Cod sursa (job #2768879) | Cod sursa (job #3237488)
#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;
}