#include <iostream>
#include <limits>
using namespace std;
const int MAX = 2000;
int arrayc[MAX][MAX];
int cost[MAX][MAX];
int main() {
int n;
cin >> n;
for(int i=0; i<n; ++i)
for(int j=i; j<n; ++j)
cin >> arrayc[i][j];
//koszt odkrycia kubka jest znany
for(int i=0; i<n; ++i) cost[i][i] = arrayc[i][i];
for(int k=1; k+1 <= n; ++k) //rozmiar przedziału to k+1
for(int i=0; i+k < n; ++i) { //początek przedziału
int j = i+k; //koniec przedziału
//rozważam przedział [i,j]
int tempCost = numeric_limits<int>::max();
//dzielę go na [a,b], [c,d], gdzie
//[a,b] jest w pełni znany
//[c,d] może przecinać [a,b], wtedy ma składową znaną
int a = i;
int d = j;
for(int b=j-1; a <= b; --b) {
int c = b+1; //[c,d] nie przecina [a,b]
int val = cost[a][b] + cost[c][d];
if(val < tempCost) tempCost = val;
//[c,d] przecina [a,b]
//minimum arrayc[c][d]
--c; //c=b
int min = arrayc[c][d];
for(--c; c >= a; --c)
if(arrayc[c][d] < min) min = arrayc[c][d];
int val2 = 0;
//gdy przedział [b+1,d] co najmniej 2 elementowy
if(d-b >= 2) {
//mniejszy z kosztów [b+2,d], [b+1,d-1]
if(cost[b+2][d] < cost[b+1][d-1]) val2 = cost[b+2][d];
else val2 = cost[b+1][d-1];
}
val = cost[a][b] + min + val2;
if(val < tempCost) tempCost = val;
}
int b = j;
int c = i;
for(int a=i+1; a <= b; ++a) {
int d = a-1;
int val = cost[a][b] + cost[c][d];
if(val < tempCost) tempCost = val;
++d;
int min = arrayc[c][d];
for(++d; d<=b; ++d)
if(arrayc[c][d] < min) min = arrayc[c][d];
int val2 = 0;
//gdy przedział [c,a-1] co najmniej 2 elementowy
if(a-c >= 2) {
//mniejszy z kosztów [c,a-2], [c+1,a-1]
if(cost[c][a-2] < cost[c+1][a-1]) val2 = cost[c][a-2];
else val2 = cost[c+1][a-1];
}
val = cost[a][b] + min + val2;
if(val < tempCost) tempCost = val;
}
cost[i][j] = tempCost;
}
cout << cost[0][n-1] << endl;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | #include <iostream> #include <limits> using namespace std; const int MAX = 2000; int arrayc[MAX][MAX]; int cost[MAX][MAX]; int main() { int n; cin >> n; for(int i=0; i<n; ++i) for(int j=i; j<n; ++j) cin >> arrayc[i][j]; //koszt odkrycia kubka jest znany for(int i=0; i<n; ++i) cost[i][i] = arrayc[i][i]; for(int k=1; k+1 <= n; ++k) //rozmiar przedziału to k+1 for(int i=0; i+k < n; ++i) { //początek przedziału int j = i+k; //koniec przedziału //rozważam przedział [i,j] int tempCost = numeric_limits<int>::max(); //dzielę go na [a,b], [c,d], gdzie //[a,b] jest w pełni znany //[c,d] może przecinać [a,b], wtedy ma składową znaną int a = i; int d = j; for(int b=j-1; a <= b; --b) { int c = b+1; //[c,d] nie przecina [a,b] int val = cost[a][b] + cost[c][d]; if(val < tempCost) tempCost = val; //[c,d] przecina [a,b] //minimum arrayc[c][d] --c; //c=b int min = arrayc[c][d]; for(--c; c >= a; --c) if(arrayc[c][d] < min) min = arrayc[c][d]; int val2 = 0; //gdy przedział [b+1,d] co najmniej 2 elementowy if(d-b >= 2) { //mniejszy z kosztów [b+2,d], [b+1,d-1] if(cost[b+2][d] < cost[b+1][d-1]) val2 = cost[b+2][d]; else val2 = cost[b+1][d-1]; } val = cost[a][b] + min + val2; if(val < tempCost) tempCost = val; } int b = j; int c = i; for(int a=i+1; a <= b; ++a) { int d = a-1; int val = cost[a][b] + cost[c][d]; if(val < tempCost) tempCost = val; ++d; int min = arrayc[c][d]; for(++d; d<=b; ++d) if(arrayc[c][d] < min) min = arrayc[c][d]; int val2 = 0; //gdy przedział [c,a-1] co najmniej 2 elementowy if(a-c >= 2) { //mniejszy z kosztów [c,a-2], [c+1,a-1] if(cost[c][a-2] < cost[c+1][a-1]) val2 = cost[c][a-2]; else val2 = cost[c+1][a-1]; } val = cost[a][b] + min + val2; if(val < tempCost) tempCost = val; } cost[i][j] = tempCost; } cout << cost[0][n-1] << endl; } |
English