Advertisement
Guest User

Untitled

a guest
Apr 24th, 2017
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.21 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include <string>
  6. #include <vector>
  7. #include <algorithm>
  8. #include <set>
  9. #include <map>
  10. #include <cmath>
  11. #include <ctime>
  12. #include <functional>
  13. #include <sstream>
  14. #include <fstream>
  15. #include <valarray>
  16. #include <complex>
  17. #include <queue>
  18. #include <cassert>
  19. #include <bitset>
  20. using namespace std;
  21.  
  22. #ifdef LOCAL
  23.     #define debug_flag 1
  24. #else
  25.     #define debug_flag 0
  26. #endif
  27.  
  28. template <class T1, class T2 >
  29. std::ostream& operator << (std::ostream& os, const pair<T1, T2> &p)
  30. {
  31.     os << "[" << p.first << ", " << p.second << "]";
  32.     return os;
  33. }
  34.  
  35. template <class T >
  36. std::ostream& operator << (std::ostream& os, const std::vector<T>& v)
  37. {
  38.     os << "[";
  39.     bool first = true;
  40.     for (typename std::vector<T>::const_iterator it = v.begin(); it != v.end(); ++it)
  41.     {
  42.         if (!first)
  43.             os << ", ";
  44.         first = false;
  45.         os << *it;
  46.     }
  47.     os << "]";
  48.     return os;
  49. }
  50.  
  51. #define dbg(args...) { if (debug_flag) { _print(_split(#args, ',').begin(), args); cerr << endl; } else { void(0);} }
  52.  
  53. vector<string> _split(const string& s, char c) {
  54.     vector<string> v;
  55.     stringstream ss(s);
  56.     string x;
  57.     while (getline(ss, x, c))
  58.         v.emplace_back(x);
  59.     return v;
  60. }
  61.  
  62. void _print(vector<string>::iterator) {}
  63. template<typename T, typename... Args>
  64. void _print(vector<string>::iterator it, T a, Args... args) {
  65.     string name = it -> substr((*it)[0] == ' ', it -> length());
  66.     if (isalpha(name[0]))
  67.         cerr << name  << " = " << a << " ";
  68.     else
  69.         cerr << name << " ";
  70.     _print(++it, args...);
  71. }
  72.  
  73. typedef long long int int64;
  74.  
  75. const int64 int64_INF = (int64)1e18;
  76.  
  77. namespace Slow
  78. {
  79.     int n;
  80.     vector<int64> p_list;
  81.     vector<int> d_list;
  82.  
  83.     int64 best_ans;
  84.  
  85.     set<vector<int64> > used;
  86.  
  87.     bool are_all_same(const vector<int> & l)
  88.     {
  89.         for (int i = 1; i < (int)l.size(); i++)
  90.             if (l[0] != l[i])
  91.                 return false;
  92.         return true;
  93.     }
  94.  
  95.     vector<int64> get_state(int64 cur_ans, vector<int> colors, vector<int> cur_dist)
  96.     {
  97.         vector<int64> state;
  98.  
  99.         state.push_back(cur_ans);
  100.  
  101.         for (int64 x : colors)
  102.             state.push_back(x);
  103.  
  104.         for (int64 x : cur_dist)
  105.             state.push_back(x);
  106.  
  107.         return state;
  108.     }
  109.  
  110.     void rec(int64 cur_ans, vector<int> colors, vector<int> cur_d_list)
  111.     {
  112.         if (cur_ans >= best_ans)
  113.             return;
  114.  
  115.         vector<int64> state = get_state(cur_ans, colors, cur_d_list);
  116.  
  117.         if (used.count(state) == 1)
  118.             return;
  119.  
  120.         used.insert(state);
  121.  
  122.         if (are_all_same(colors))
  123.         {
  124.             best_ans = min(best_ans, cur_ans);
  125.             return;
  126.         }
  127.  
  128.         for (int i = 0; i < n; i++)
  129.         {
  130.             for (int j = i + 1; j < n; j++)
  131.             {
  132.                 if (colors[i] != colors[j] && cur_d_list[i] >= 1 && cur_d_list[j] >= 1)
  133.                 {
  134.                     cur_d_list[i]--;
  135.                     cur_d_list[j]--;
  136.                    
  137.                     vector<int> new_colors = colors;
  138.                     int x = colors[i];
  139.                     int y = colors[j];
  140.  
  141.                     for (int & c : new_colors)
  142.                         if (c == x)
  143.                             c = y;
  144.  
  145.                     rec(cur_ans + abs(p_list[i] - p_list[j]), new_colors, cur_d_list);
  146.  
  147.                     cur_d_list[i]++;
  148.                     cur_d_list[j]++;
  149.                 }
  150.             }
  151.         }
  152.     }
  153.  
  154.     int64 solve(int _n, vector<int64> _p_list, vector<int> _d_list)
  155.     {
  156.         n = _n;
  157.         p_list = _p_list;
  158.         d_list = _d_list;
  159.  
  160.         best_ans = int64_INF;
  161.  
  162.         vector<int> colors(n);
  163.         for (int i = 0; i < n; i++)
  164.             colors[i] = i;
  165.        
  166.         rec(0, colors, d_list);
  167.  
  168.         if (best_ans == int64_INF)
  169.             best_ans = -1;
  170.  
  171.         return best_ans;
  172.     }
  173.  
  174. };
  175.  
  176. namespace Fast
  177. {
  178.     int n;
  179.     vector<int64> p_list;
  180.     vector<int> d_list;
  181.  
  182.     bool cmp_by_p(int a, int b)
  183.     {
  184.         return p_list[a] < p_list[b];
  185.     }
  186.  
  187.     int64 get_dist(int a, int b)
  188.     {
  189.         return abs(p_list[a] - p_list[b]);
  190.     }
  191.  
  192.     int64 solve(int _n, vector<int64> _p_list, vector<int> _d_list)
  193.     {
  194.         n = _n;
  195.         p_list = _p_list;
  196.         d_list = _d_list;
  197.  
  198.         if (n <= 2)
  199.         {
  200.             return Slow::solve(n, p_list, d_list);
  201.         }
  202.    
  203.         vector<int> small_list;
  204.         vector<int> big_list;
  205.  
  206.         for (int i = 0; i < n; i++)
  207.         {
  208.             if (d_list[i] == 1)
  209.             {
  210.                 small_list.push_back(i);
  211.             }
  212.             else
  213.             {
  214.                 big_list.push_back(i);
  215.             }
  216.         }
  217.  
  218.         int small_size = (int)small_list.size();
  219.         int big_size = (int)big_list.size();
  220.        
  221.         sort(small_list.begin(), small_list.end(), cmp_by_p);
  222.         sort(big_list.begin(), big_list.end(), cmp_by_p);
  223.  
  224.         if (big_size == 0)
  225.             return -1;
  226.  
  227.         int64 ans0 = 0;
  228.  
  229.         for (int i = 0; i + 1 < big_size; i++)
  230.         {
  231.             int a = big_list[i];
  232.             int b = big_list[i + 1];
  233.             if (d_list[a] == 0 || d_list[b] == 0)
  234.                 return -1;
  235.             d_list[a]--;
  236.             d_list[b]--;
  237.             ans0 += get_dist(a, b);
  238.         }
  239.  
  240.         dbg(ans0);
  241.         dbg(small_list);
  242.         dbg(big_list);
  243.         dbg("d_list after", d_list);
  244.  
  245.         vector<int64> dp(small_size + 1, int64_INF);
  246.         dp[0] = 0;
  247.  
  248.         for (int i = 0; i < (int)big_list.size(); i++)
  249.         {
  250.             vector<int64> new_dp = dp;
  251.  
  252.             for (int j = 1; j <= small_size; j++)
  253.             {
  254.                 int l = max(1, j - d_list[i] + 1);
  255.                 int r = j;
  256.  
  257.                 int64 sum = 0;
  258.                 for (int t = r; t >= l; t--)
  259.                 {
  260.                     sum += get_dist(big_list[i], small_list[t - 1]);
  261.                     int64 cur_val = sum + dp[t - 1];
  262.                     new_dp[j] = min(new_dp[j], cur_val);
  263.                 }
  264.             }
  265.  
  266.             dp = new_dp;
  267.         }
  268.  
  269.         int64 ans1 = dp[small_size];
  270.  
  271.         if (ans1 == int64_INF)
  272.             return -1;
  273.  
  274.         return ans0 + ans1;
  275.     }
  276. };
  277.  
  278. void submit()
  279. {
  280.     int n;
  281.     scanf("%d", &n);
  282.     vector<int64> p_list(n);
  283.     vector<int> d_list(n);
  284.     for (int i = 0; i < n; i++)
  285.     {
  286.         scanf("%lld%d", &p_list[i], &d_list[i]);
  287.     }
  288.  
  289.     int64 ans = Slow::solve(n, p_list, d_list);
  290.  
  291.     printf("%lld\n", ans);
  292. }
  293.  
  294. void stress()
  295. {
  296.     const int IT = 1e5;
  297.  
  298.     const int N = 3;
  299.     const int P = 3;
  300.     const int D = 3;
  301.  
  302.     for (int it = 0; it < IT; it++)
  303.     {
  304.         printf("it = %d\n", it);
  305.  
  306.         int n = rand() % N + 1;
  307.         vector<int64> p_list(n);
  308.         vector<int> d_list(n);
  309.         for (int i = 0; i < n; i++)
  310.         {
  311.             p_list[i] = rand() % P + 1;
  312.             d_list[i] = rand() % D + 1;
  313.         }
  314.  
  315.         int64 fast_ans = Fast::solve(n, p_list, d_list);
  316.         int64 slow_ans = Slow::solve(n, p_list, d_list);
  317.  
  318.         if (fast_ans != slow_ans)
  319.         {
  320.             printf("fast_ans = %lld slow_ans = %lld\n", fast_ans, slow_ans);
  321.             printf("%d\n", n);
  322.             for (int i = 0; i < n; i++)
  323.             {
  324.                 printf("%lld %d\n", p_list[i], d_list[i]);
  325.             }
  326.             return;
  327.         }
  328.     }
  329.  
  330.     printf("stress passed\n");
  331. }
  332.  
  333. int main()
  334. {
  335. #ifdef LOCAL
  336.     freopen ("input.txt", "r", stdin);
  337. #endif
  338.  
  339.     submit();
  340.  
  341.     //stress();
  342.    
  343.     return 0;
  344. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement