#include <vector>
#include <list>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <string>
#include <cassert> // TODO
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define FORD(i,a,b) for(int i=(a);i>=(b);--i)
#define REP(i,a) FOR(i,0,a)
#define MP make_pair
#define PB push_back
#define ST first
#define ND second
using namespace std;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef pair<int, int> PII;
typedef vector<PII> VII;
typedef long long int LL;
typedef unsigned long long int ULL;
const int MAXNN = 2000 * 2001 / 2 + 5;
const int MAXN = 2005;
int n;
PII costs[MAXNN];
PII interval[MAXNN];
int base[MAXN];
bool exists[MAXN][MAXN];
void mark(int beg, int end) {
exists[beg][end] = true;
FOR (i, 1, beg) {
if (exists[i][beg-1]) exists[i][end] = true;
}
FOR (i, end+1, n) {
if (exists[end+1][i]) exists[beg][i] = true;
}
}
bool insert(int indx) {
int beg = interval[costs[indx].ND].ST;
int end = interval[costs[indx].ND].ND;
int tmp;
if (exists[beg][end]) {
return false;
}
while (base[beg] != 0) {
if (base[beg] == end) {
return false;
}
else {
tmp = beg;
beg = min(end, base[beg]) + 1;
end = max(end, base[tmp]);
}
}
if (beg > n) {
return false;
}
beg = interval[costs[indx].ND].ST;
end = interval[costs[indx].ND].ND;
while (base[beg] != 0) {
mark(beg, end);
tmp = beg;
beg = min(end, base[beg]) + 1;
end = max(end, base[tmp]);
base[tmp] = end;
}
mark(beg, end);
base[beg] = end;
return true;
}
int main() {
scanf("%d", &n);
int indx = 0;
REP (i, n) {
REP (j, n-i) {
scanf("%d", &(costs[indx].ST));
costs[indx].ND = indx;
interval[indx] = {i+1, i+j+1};
++indx;
}
}
sort(costs, costs + indx);
indx = 0;
LL res = 0;
REP (i, n) {
while (!insert(indx)) {
++indx;
}
res += costs[indx].ST;
++indx;
}
printf("%lld\n", res);
return 0;
}
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 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | #include <vector> #include <list> #include <map> #include <set> #include <unordered_map> #include <unordered_set> #include <deque> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> #include <iostream> #include <string> #include <cassert> // TODO #define FOR(i,a,b) for(int i=(a);i<(b);++i) #define FORD(i,a,b) for(int i=(a);i>=(b);--i) #define REP(i,a) FOR(i,0,a) #define MP make_pair #define PB push_back #define ST first #define ND second using namespace std; typedef vector<int> VI; typedef vector<VI> VVI; typedef pair<int, int> PII; typedef vector<PII> VII; typedef long long int LL; typedef unsigned long long int ULL; const int MAXNN = 2000 * 2001 / 2 + 5; const int MAXN = 2005; int n; PII costs[MAXNN]; PII interval[MAXNN]; int base[MAXN]; bool exists[MAXN][MAXN]; void mark(int beg, int end) { exists[beg][end] = true; FOR (i, 1, beg) { if (exists[i][beg-1]) exists[i][end] = true; } FOR (i, end+1, n) { if (exists[end+1][i]) exists[beg][i] = true; } } bool insert(int indx) { int beg = interval[costs[indx].ND].ST; int end = interval[costs[indx].ND].ND; int tmp; if (exists[beg][end]) { return false; } while (base[beg] != 0) { if (base[beg] == end) { return false; } else { tmp = beg; beg = min(end, base[beg]) + 1; end = max(end, base[tmp]); } } if (beg > n) { return false; } beg = interval[costs[indx].ND].ST; end = interval[costs[indx].ND].ND; while (base[beg] != 0) { mark(beg, end); tmp = beg; beg = min(end, base[beg]) + 1; end = max(end, base[tmp]); base[tmp] = end; } mark(beg, end); base[beg] = end; return true; } int main() { scanf("%d", &n); int indx = 0; REP (i, n) { REP (j, n-i) { scanf("%d", &(costs[indx].ST)); costs[indx].ND = indx; interval[indx] = {i+1, i+j+1}; ++indx; } } sort(costs, costs + indx); indx = 0; LL res = 0; REP (i, n) { while (!insert(indx)) { ++indx; } res += costs[indx].ST; ++indx; } printf("%lld\n", res); return 0; } |
English