Pagini recente » Cod sursa (job #218836) | Cod sursa (job #1081848) | Cod sursa (job #1840729) | Cod sursa (job #3291774) | Cod sursa (job #3239555)
#include <bits/stdc++.h>
using namespace std;
/**
* @brief dp[i][j] = numarul minim de inmultiri scalare cu
* care se poate obține produsul Mi ∗ Mi+1 ∗ ... ∗ Mj
*
* dp[i][j] = min(dp[i][k] + dp[k + 1][j] + d[i - 1] * d[k] * d[j]), k = i : j - 1
*/
class Task { // T = O(n ^ 3), S = O(n ^ 2)
public:
void solve() {
read_input();
print_output(get_result());
}
private:
int n;
vector<int32_t> d;
void read_input() {
ifstream fin("podm.in");
fin.tie(0);
fin >> n;
d.resize(n + 1);
for (int i = 0; i <= n; i++) {
fin >> d[i];
}
fin.close();
}
uint64_t get_result() {
vector<vector<uint64_t>> dp(n + 1, vector<uint64_t> (n + 1, UINT64_MAX));
// caz de baza 1: nu am ce înmulți
for (int i = 1; i <= n; ++i) {
dp[i][i] = 0ULL;
}
// caz de baza 2: matrice d[i - 1] x d[i] înmulțită cu matrice d[i] x d[i + 1]
// (matrice pe poziții consecutive)
for (int i = 1; i < n; ++i) {
dp[i][i + 1] = 1ULL * d[i - 1] * d[i] * d[i + 1];
}
// caz general
for (int len = 2; len <= n; ++len) { // fixăm lungimea intervalului (2, 3, 4, ...)
for (int i = 1; i + len - 1 <= n; ++i) { // fixăm capătul din stânga: i
int j = i + len - 1; // capătul din dreapta se deduce: j
// Iterăm prin indicii dintre capete, spărgând șirul de înmulțiri in două (paranteze).
for (int k = i; k < j; ++k) {
// M_i * ... M_j = (M_i * .. * M_k) * (M_k+1 *... * M_j)
uint64_t new_sol = dp[i][k] + dp[k + 1][j] + 1ULL * d[i - 1] * d[k] * d[j];
// actualizăm soluția dacă este mai bună
dp[i][j] = min(dp[i][j], new_sol);
}
}
}
return dp[1][n];
}
void print_output(uint64_t result) {
ofstream fout("podm.out");
fout.tie(0);
fout << result << "\n";
fout.close();
}
};
int main() {
ios::sync_with_stdio(false);
auto* task = new (nothrow) Task();
if (!task) {
cerr << "new failed\n";
return -1;
}
task->solve();
delete task;
return 0;
}