#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; } |