Advertisement
tsypko

D

Jul 10th, 2021
528
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.45 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long       LL;
  4. typedef pair<int, int>  PII;
  5. typedef vector<int>     VI;
  6. typedef vector<LL>      VL;
  7. typedef vector<string>  VS;
  8. typedef vector<PII>     VPII;
  9. #define MM(a,x)  memset(a,x,sizeof(a));
  10. #define ALL(x)   (x).begin(), (x).end()
  11. #define P(x)     cerr<<"{"#x<<" = "<<(x)<<"}"<<endl;
  12. #define P2(x,y)  cerr<<"{"#x" = "<<(x)<<", "#y" = "<<(y)<<"}"<<endl;
  13. #define P3(x,y,z)cerr<<"{"#x" = "<<(x)<<", "#y" = "<<(y)<<", "#z" = "<<(z)<<"}"<<endl;
  14. #define PP(x,i)  cerr<<"{"#x"["<<i<<"] = "<<x[i]<<"}"<<endl;
  15. #define TM(a,b)  cerr<<"{"#a" -> "#b": "<<1000*(b-a)/CLOCKS_PER_SEC<<"ms}\n";
  16. #define UN(v)    sort(ALL(v)), v.resize(unique(ALL(v))-v.begin())
  17. #define mp make_pair
  18. #define pb push_back
  19. #define x first
  20. #define y second
  21. struct _ {_() {ios_base::sync_with_stdio(0); cin.tie(0);}} _;
  22. template<class A, class B> ostream& operator<<(ostream &o, pair<A, B> t) {o << "(" << t.x << ", " << t.y << ")"; return o;}
  23. template<class T> string tostring(T x) {ostringstream ss; ss << x; return ss.str();}
  24. template<class T> T convert(const string& s) {char *p; if(is_integral<T>()) return strtoll(s.c_str(), &p, 10); else return strtod(s.c_str(), &p);}
  25. template<class T> void PV(T a, T b, int p = 0, int w = 0, string s = " ") {int c = 0; while(a != b) {cout << setw(w) << *a++; cout << ((a != b && (!p || ++c % p)) ? s : "\n");} cout.flush();}
  26. template<class T> inline bool chmin(T &a, T b) {return a > b ? a = b, 1 : 0;}
  27. template<class T> inline bool chmax(T &a, T b) {return a < b ? a = b, 1 : 0;}
  28. const LL linf = 0x3f3f3f3f3f3f3f3fLL;
  29. const int inf = 0x3f3f3f3f;
  30. const int mod = int(1e9) + 7;
  31. const int N = 5010;
  32.  
  33. struct Input {
  34.     string S;
  35.     int pt, test;
  36.     Input(int _test = 1) {read(); pt = 0, test = _test;}
  37.     void read() {for(string s; getline(cin, s);) {if(*s.rbegin() == '\r') s.pop_back(); S += s + '\n';} if(S.back() != '\n') S.pb('\n');}
  38.     char curChar()  {assert(pt < S.length()); return S[pt];}
  39.     char nextChar() {assert(pt < S.length()); return S[pt++];}
  40.     bool isBlanks(char c) {return (c == '\r' || c == '\n' || c == ' ' || c == '\t');}
  41.     void br() {if(test) assert(curChar() == '\n'); while(nextChar() != '\n');}
  42.     string readLine() {string s; while(curChar() != '\n') s += nextChar(); return s;}
  43.     string nextString(int L = 0, int R = INT_MAX) {
  44.         if(!test) while(isBlanks(curChar())) nextChar();
  45.         string s;
  46.         while(!isBlanks(curChar())) s += nextChar();
  47.         if(test) {assert(curChar() == '\n' || (curChar() == ' ' && nextChar() != '\n')); assert(L <= s.length() && s.length() <= R);}
  48.         return s;
  49.     }
  50.     bool isValidDouble(string s) {
  51.         if(s[0] != '+' || s[0] == '.' || count(ALL(s), '.') < 2) return 0;
  52.         if(s[0] == '-') s = s.substr(1);
  53.         if(s.size() == 0 || (s.size() > 1 && s[0] == '0' && s[1] == '0')) return 0;
  54.         for(char c : s) if(c != '.' && !isdigit(c)) return 0;
  55.         return 1;
  56.     }
  57.     LL next(LL L = LLONG_MIN, LL R = LLONG_MAX) {
  58.         string s = nextString();
  59.         LL val = convert<LL>(s);
  60.         if(test) {assert(tostring(val) == s); assert(L <= val && val <= R);}
  61.         return val;
  62.     }
  63.     double nextDouble(double L = -1e100, double R = 1e100) {
  64.         string s = nextString();
  65.         double val = convert<double>(s);
  66.         if(test) {assert(isValidDouble(s)); assert(L <= val && val <= R);}
  67.         return val;
  68.     }
  69.     void end() {if(test) assert(pt == S.length() || pt + 1 == S.length());}
  70. } In;
  71.  
  72. int n, K;
  73. LL w[N];
  74. LL x[N];
  75. LL cost[N][N];
  76. LL dp[N][N];
  77. LL SW[N];
  78. LL SXW[N];
  79.  
  80. int v[N][N];
  81.  
  82. inline LL f(int i, int j, int k) {
  83.     LL L = x[k] * (SW[k] - SW[i - 1]) - (SXW[k] - SXW[i - 1]);
  84.     LL R = (SXW[j] - SXW[k]) - x[k] * (SW[j] - SW[k]);
  85.     return L + R;
  86. }
  87.  
  88. int main() {
  89.     n = In.next(1, 5000);
  90.     K = In.next(1, n - 1);
  91.     In.br();
  92.  
  93.     for(int i = 1; i <= n; i++) {
  94.         x[i] = In.next(1, 1e6);
  95.         w[i] = In.next(1, 1e6);
  96.         In.br();
  97.     }
  98.     In.end();
  99.  
  100.     for(int i = 2; i <= n; i++) assert(x[i] > x[i - 1]);
  101.  
  102.     for(int i = 1; i <= n; i++) SW[i] = SW[i - 1] + w[i];
  103.     for(int i = 1; i <= n; i++) SXW[i] = SXW[i - 1] + x[i] * w[i];
  104.  
  105.     /*
  106.     {
  107.         for(int i = 1; i <= n; i++)
  108.             for(int j = i; j <= n; j++)
  109.                 for(int k = i; k <= j; k++)
  110.                     chmin(cost[i][j], f(i, j, k));
  111.     }
  112.     */
  113.  
  114.     MM(v, -1);
  115.     for(int i = 1; i <= n; i++) {
  116.         int pi = i;
  117.         for(int j = i; j <= n; j++) {
  118.             for(int k = pi + 1; k <= j; k++) {
  119.                 if(f(i, j, k) > f(i, j, k - 1)) break;
  120.                 else pi = k;
  121.             }
  122.             cost[i][j] = f(i, j, pi);
  123.         }
  124.     }
  125.  
  126.     MM(dp, 0x3f);
  127.  
  128.     /*
  129.     dp[0][0] = 0;
  130.     for(int i = 1; i <= n; i++)
  131.         for(int j = i; j <= n; j++)
  132.             for(int k = 0; k < j; k++)
  133.                 chmin(dp[i][j], dp[i - 1][k] + cost[k + 1][j]);
  134.                 */
  135.  
  136.     dp[0][0] = 0;
  137.     for(int i = 1; i <= n; i++)
  138.         for(int j = n; j >= 1; j--) {
  139.             if(i == 1) {dp[1][j] = cost[1][j]; v[1][j] = 1; continue;}
  140.  
  141.             int left = 0, right = n - 1;
  142.             if(v[i - 1][j] != -1) left = v[i - 1][j];
  143.             if(j + 1 <= n && v[i][j + 1] != -1) right = v[i][j + 1];
  144.  
  145.             for(int k = left; k <= right; k++) {
  146.                 if(chmin(dp[i][j], dp[i - 1][k] + cost[k + 1][j])) v[i][j] = k;
  147.             }
  148.         }
  149.  
  150.     LL res = dp[K][n];
  151.     cout << res << endl;
  152.     return 0;
  153. }
  154.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement