Good Bye 2017 F. New Year and Rainbow Roads[模拟][贪心]

题目:http://codeforces.com/contest/908/problem/F

题意:给出n个点和他所在坐标,每个点有R,G,B三种颜色中的一种,坐标严格递增。要求在删除所有R或删除所有B后的所有点必须直接或间接链接在一起,每一次链接的代价为距离差,求最小代价。

分析:考虑以G为分隔符,每次处理每一段两个相邻G点之间的所有R和B(两个G中间有R且有B的情况),如果想让删除R或B后依然链接,有两种最优化策略。

*第一种,两个G点通过中间的R和B相连,长度为(posG[i+1]-posG[i])*2,这样在删除哪一种点以后另一种点都可以链接两端的G。
*第二种,两个G点互相连接,并从两个G点向外延伸线段连接R和B,长度为(posG[i+1]-posG[i])*3-ansR-ansB ansR代表相邻的R和G点的最长间隔,因为有两个G相连,所以在B的线段上删除一条间隔时不会断开链接,例如GBRG,如果B离第一个G更远则删除他和第一个G的链接,所以找最长的间隔删除,ansB同理。可以在线性时间内处理每一对相邻G点。

*其他中间没有B或R的情况类似处理。
*边缘的B直接串成一串链接到最近的G为最优答案,R同理。

*对于没有G的特殊情况,直接链接所有的R和所有的B即可。

代码:

  1 #define _CRT_SECURE_NO_DEPRECATE
  2 #pragma comment(linker, "/STACK:102400000,102400000")
  3 #pragma GCC optimize("Ofast")
  4 #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  5 #include<iostream>  
  6 #include<cstdio>  
  7 #include<fstream>  
  8 #include<iomanip>
  9 #include<algorithm>  
 10 #include<cmath>  
 11 #include<deque>  
 12 #include<vector>
 13 #include<bitset>
 14 #include<queue>  
 15 #include<string>  
 16 #include<cstring>  
 17 #include<map>  
 18 #include<stack>  
 19 #include<set>
 20 #include<functional>
 21 #define pii pair<ll,ll>
 22 #define mod 1000000007
 23 #define mp make_pair
 24 #define pi acos(-1)
 25 #define eps 0.00000001
 26 #define mst(a,i) memset(a,i,sizeof(a))
 27 #define all(n) n.begin(),n.end()
 28 #define lson(x) ((x<<1))  
 29 #define rson(x) ((x<<1)|1) 
 30 #define inf 0x3f3f3f3f
 31 typedef long long ll;
 32 typedef unsigned long long ull;
 33 using namespace std;
 34 const ll maxn = 3e5 + 5;
 35 pii a[maxn];
 36 vector<ll>r, g, b;
 37 int main()
 38 {
 39     ios::sync_with_stdio(false);
 40     cin.tie(0); cout.tie(0);
 41     ll i, j, k, m, n;
 42     cin >> n;
 43     char ch;
 44     ll mode = 0;
 45     for (ll i = 1; i <= n; ++i)
 46     {
 47         cin >> a[i].first >> ch;
 48         if (ch == 'R') { a[i].second = 1; r.push_back(a[i].first); }
 49         else if (ch == 'B') { a[i].second = 2; b.push_back(a[i].first); }
 50         else { a[i].second = 3; g.push_back(a[i].first); }
 51         if (ch == 'G')mode = 1;
 52     }
 53     ll ans = 0;
 54 
 55     if (mode == 0)
 56     {
 57         ll pre = -1;
 58         for (ll i = 1; i <= n; ++i)
 59         {
 60             if (a[i].second != 1)continue;
 61             if (pre != -1)ans += a[i].first - pre;
 62             pre = a[i].first;
 63         }
 64         pre = -1;
 65         for (ll i = 1; i <= n; ++i)
 66         {
 67             if (a[i].second != 2)continue;
 68             if (pre != -1)ans += a[i].first - pre;
 69             pre = a[i].first;
 70         }
 71     }
 72     else
 73     {
 74         for (ll i = 0; i < g.size(); ++i)
 75         {
 76             if (i == 0)
 77             {
 78                 ll cas = lower_bound(b.begin(), b.end(), g[i]) - b.begin();
 79                 if (cas != 0)ans += g[i] - b[0];
 80                 cas = lower_bound(r.begin(), r.end(), g[i]) - r.begin();
 81                 if (cas != 0)ans += g[i] - r[0];
 82             }
 83             if (i == g.size() - 1)
 84             {
 85                 ll cas = lower_bound(b.begin(), b.end(), g[i]) - b.begin();
 86                 if (cas != b.size())ans += b[b.size() - 1] - g[i];
 87                 cas = lower_bound(r.begin(), r.end(), g[i]) - r.begin();
 88                 if (cas != r.size())ans += r[r.size() - 1] - g[i];
 89             }
 90             if (i != g.size() - 1)
 91             {
 92                 ll maxa = inf, maxb = inf;
 93                 ll st = lower_bound(b.begin(), b.end(), g[i]) - b.begin();
 94                 ll ed = lower_bound(b.begin(), b.end(), g[i + 1]) - b.begin() - 1;
 95                 if (st < b.size() && b[st] < g[i + 1])
 96                 {
 97                     ll temp = b[st] - g[i];
 98                     temp = max(temp, g[i + 1] - b[ed]);
 99                     for (ll j = st + 1; j <= ed; ++j)
100                         temp = max(temp, b[j] - b[j - 1]);
101                     maxa = temp;
102                 }
103                 st = lower_bound(r.begin(), r.end(), g[i]) - r.begin();
104                 ed = lower_bound(r.begin(), r.end(), g[i + 1]) - r.begin() - 1;
105                 if (st<r.size()&&r[st] < g[i + 1])
106                 {
107                     ll temp = r[st] - g[i];
108                     temp = max(temp, g[i + 1] - r[ed]);
109                     for (ll j = st + 1; j <= ed; ++j)
110                         temp = max(temp, r[j] - r[j - 1]);
111                     maxb = temp;
112                 }
113                 ll sum = g[i + 1] - g[i];
114                 if (maxa == inf&&maxb == inf)ans += sum;
115                 else if (maxa == inf)ans += sum + sum - maxb;
116                 else if (maxb == inf)ans += sum + sum - maxa;
117                 else
118                     ans += min(sum * 2LL, sum * 3LL - maxa - maxb);
119             }
120         }
121     }
122     cout << ans << endl;
123     return 0;
124 }

 

posted @ 2017-12-30 22:25  Meternal  阅读(650)  评论(0编辑  收藏  举报