#include <iostream> #include <vector> #include <algorithm> #include <cmath> using namespace std; struct ij{ int i; int j; }; struct interval{ int min_v; int max_v; int len; int cov; std::vector<interval> children; bool is_contained(const interval &i) const{ return this->min_v <= i.min_v && this->max_v >= i.max_v; } bool is_overlapped(const interval &i) const{ return this->min_v >= i.max_v || this->max_v <= i.min_v; } bool is_closed(){ return len==cov; } bool is_useful(const interval &x){ for( interval &i : children ){ if( i.is_contained(x) && i.is_closed() ) return false; } bool b = true; for( interval &i : children ){ if( i.is_contained(x) ) b = b && i.is_useful(x); } return b; } void insert(const interval &x){ this->cov++; for( interval &i : children ){ if( i.is_contained(x) ){ i.insert(x); } else if( i.is_overlapped(x) ){ interval tmp = i; i.children.clear(); i.min_v = min(i.min_v,x.min_v); i.max_v = max(i.max_v,x.max_v); i.len = i.max_v - i.min_v +1; i.cov = i.cov + 1; i.children.push_back(tmp); i.children.push_back(x); }else{ this->children.push_back(x); } } } static interval get_interval(ij a,int visited){ return {a.i,a.j,a.j-a.i+1,visited,std::vector<interval>()}; } }; int read_input(){ std::vector<ij> ind; std::vector<std::vector<int>> vec; int n; cin>>n; vec.reserve(n); ind.reserve(n*(n-1)/2); for( int i=0; i<n; i++ ){ vec.push_back(move(std::vector<int>())); vec[i].reserve(n-i); for( int j=0; j<n-i; j++){ int tmp; cin>>tmp; vec[i].push_back(tmp); ind.push_back({i,j}); } } sort( ind.begin(), ind.end(), [&vec](const ij &a,const ij &b)->bool{ return vec[a.i][a.j] < vec[b.i][b.j]; } ); interval root = interval::get_interval({0,n-1},0); int cost = 0; for(ij a : ind){ interval i = interval::get_interval(a,1); if( root.is_useful(i) ){ cost += vec[a.i][a.j]; root.insert(i); } if( root.is_closed() ){ cout<<cost<<endl; return cost; } } return 0; } int main(){ read_input(); 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 | #include <iostream> #include <vector> #include <algorithm> #include <cmath> using namespace std; struct ij{ int i; int j; }; struct interval{ int min_v; int max_v; int len; int cov; std::vector<interval> children; bool is_contained(const interval &i) const{ return this->min_v <= i.min_v && this->max_v >= i.max_v; } bool is_overlapped(const interval &i) const{ return this->min_v >= i.max_v || this->max_v <= i.min_v; } bool is_closed(){ return len==cov; } bool is_useful(const interval &x){ for( interval &i : children ){ if( i.is_contained(x) && i.is_closed() ) return false; } bool b = true; for( interval &i : children ){ if( i.is_contained(x) ) b = b && i.is_useful(x); } return b; } void insert(const interval &x){ this->cov++; for( interval &i : children ){ if( i.is_contained(x) ){ i.insert(x); } else if( i.is_overlapped(x) ){ interval tmp = i; i.children.clear(); i.min_v = min(i.min_v,x.min_v); i.max_v = max(i.max_v,x.max_v); i.len = i.max_v - i.min_v +1; i.cov = i.cov + 1; i.children.push_back(tmp); i.children.push_back(x); }else{ this->children.push_back(x); } } } static interval get_interval(ij a,int visited){ return {a.i,a.j,a.j-a.i+1,visited,std::vector<interval>()}; } }; int read_input(){ std::vector<ij> ind; std::vector<std::vector<int>> vec; int n; cin>>n; vec.reserve(n); ind.reserve(n*(n-1)/2); for( int i=0; i<n; i++ ){ vec.push_back(move(std::vector<int>())); vec[i].reserve(n-i); for( int j=0; j<n-i; j++){ int tmp; cin>>tmp; vec[i].push_back(tmp); ind.push_back({i,j}); } } sort( ind.begin(), ind.end(), [&vec](const ij &a,const ij &b)->bool{ return vec[a.i][a.j] < vec[b.i][b.j]; } ); interval root = interval::get_interval({0,n-1},0); int cost = 0; for(ij a : ind){ interval i = interval::get_interval(a,1); if( root.is_useful(i) ){ cost += vec[a.i][a.j]; root.insert(i); } if( root.is_closed() ){ cout<<cost<<endl; return cost; } } return 0; } int main(){ read_input(); return 0; } |