SRM309 D2H SynchronizingGuideposts

TopCoder Statistics - Problem Statement

This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2010, TopCoder, Inc. All rights reserved.

guidepostsの$position\ distance\ limit$が与えられる.$limit$以上動かすときは余計に$C$かかる.一箇所に集めるときのコストの最小を求める.
それぞれの場所($position + distance$)とそこから$+limit$,$-limit$動かした場所を動かす場所の候補にする.intだとオーバーフローする.

Code

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
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include <queue>

#define REP(i,k,n) for(int i=k;i<n;i++)
#define rep(i,n) for(int i=0;i<n;i++)
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++)
#define INF 1LL<<60
#define mp make_pair

using namespace std;
typedef long long ll;
typedef pair<int, int> P;

vector<string> split(const string &str, char delim) {
  vector<string> res;
  size_t current = 0, found;
  while((found = str.find_first_of(delim, current)) != string::npos) {
      res.push_back(string(str, current, found - current));
      current = found + 1;
  }
  res.push_back(string(str, current, str.size() - current));
  return res;
}

class SynchronizingGuideposts {
  public:
  long long minCost(vector <string> guideposts, int C) {
      int n = guideposts.size();
      vector<ll> pos(n), dis(n), lim(n);

      rep(i, n) {
          ll x;
          vector<string> ret = split(guideposts[i], ' ');
          {
              stringstream ss(ret[0]);
              ss >> x;
              pos[i] = x;
          }
          {
              stringstream ss(ret[1]);
              ss >> x;
              dis[i] = x;
          }
          {
              stringstream ss(ret[2]);
              ss >> x;
              lim[i] = x;
          }
      }

      set<ll> st;
      st.insert(0);

      rep(i, n) {
          if(pos[i] + dis[i] - lim[i] >= 0)
              st.insert(pos[i] + dis[i] - lim[i]);
          if(pos[i] + dis[i] >= 0)
              st.insert(pos[i] + dis[i]);
          if(pos[i] + dis[i] + lim[i] >= 0)
              st.insert(pos[i] + dis[i] + lim[i]);
      }

      ll ans = INF;
      each(it, st) {
          ll sum = 0;
          rep(i, n) {
              ll res = abs(pos[i] + dis[i] - *it);
              sum += res;
              if(res > lim[i]) {
                  sum += (res - lim[i]) * C;
              }
          }

          ans = min(ans, sum);
      }

      return ans;
  }
};
Sep 3rd, 2016