hihoCoder 1391 Countries【预处理+排序+优先队列】2016北京网络赛

题目:http://hihocoder.com/problemset/problem/1391

题目大意:

  A和B两个国家互射导弹,每个国家都有一个防御系统,在防御系统开启的时间内可以将到达本国的导弹反弹回去(掉头,防御系统不能开开关关)。

  现在已知:Ta、Tb为A、B两国导弹防御能开启的持续时间,X为B国开启导弹防御系统的时刻(持续时间为[X,Tb+X],包含端点)

  A向B发射N枚导弹,B向A发射M枚导弹。每枚导弹有3个值:发射时间,从A到B或从B到A的飞行时间,伤害值。

  现在A可以在任意时刻开启防御系统,求A所受到的最小伤害值。

题目思路:

  【预处理+排序+堆】

  首先预处理,求出每枚导弹不会打到A需要A国防御系统开启的时间段[st,et],只有A开启防御的时间段[Y,Y+Ta]包含[st,et]那么这枚导弹不会打到A。

  预处理之后将每枚导弹按照et从小到大排序。

  从1到n+m枚导弹,对于当前这枚导弹,如果需要被防御,那么A防御系统的结束时间就为et,那么开启时间就为et-Ta

  那么将之前已经被防御的导弹中st<et-Ta的移除出去,表示这些导弹不能在当前决策中被防御。

  可以开个STL的优先队列或者堆记录之前被防御的导弹序号,按照st从小到大存,每次比较最小的st和开启时间et-Ta。并在过程中增减伤害值,并记录最小伤害。

  1 //#include<bits/stdc++.h>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<string>
  5 #include<iomanip>
  6 #include<map>
  7 #include<stack>
  8 #include<queue>
  9 #include<set>
 10 #include<bitset>
 11 #include<memory.h>
 12 #include<time.h>
 13 #include<stdio.h>
 14 #include<stdlib.h>
 15 #include<string.h>
 16 #include<math.h>
 17 #define min(a,b) ((a)<(b)?(a):(b))
 18 #define max(a,b) ((a)>(b)?(a):(b))
 19 #define abs(a) ((a)>0?(a):(-(a)))
 20 #define lowbit(a) (a&(-a))
 21 #define sqr(a) ((a)*(a))
 22 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
 23 #define mem(a,b) memset(a,b,sizeof(a))
 24 #define eps (1e-10)
 25 #define J 10000
 26 #define mod 1000000007
 27 #define MAX 0x7f7f7f7f
 28 #define PI 3.14159265358979323
 29 #define N 20004
 30 using namespace std;
 31 typedef long long LL;
 32 double anss;
 33 LL aans;
 34 int cas, cass;
 35 int n, m, lll, ans;
 36 int Ta, Tb, X, sum;
 37 struct xxx
 38 {
 39     LL st, ct, et, d;
 40 }a[N], b[N];
 41 struct cmp1
 42 {
 43     bool operator ()(const int &aa, const int &bb)
 44     {
 45         return a[aa].st > a[bb].st;
 46     }
 47 };
 48 bool cmp(xxx aa, xxx bb)
 49 {
 50     return aa.et < bb.et;
 51 }
 52 int main()
 53 {
 54     //    freopen("1.txt","r",stdin);
 55     //    freopen("2.txt","w",stdout);
 56     int i, j, k;
 57     int x, y, z;
 58     while (~scanf("%d%d", &Ta, &Tb))
 59     {
 60         lll = 0; ans = MAX; sum = 0;
 61         scanf("%d%d%d", &X, &n, &m);
 62         for (i = 1; i <= n; i++)
 63         {
 64             scanf("%d%d%d", &b[i].st, &b[i].ct, &b[i].d);
 65             b[i].et = b[i].st + b[i].ct;
 66             if (b[i].et >= X && b[i].et <= X + Tb)
 67             {
 68                 sum += b[i].d;
 69                 a[++lll].st = b[i].et + b[i].ct;
 70                 j = Tb + X - a[lll].st;
 71                 j = j % (2 * b[i].ct);
 72                 a[lll].et = Tb + X - j;
 73                 a[lll].d = b[i].d;
 74                 if (j >= b[i].ct)a[lll].et += b[i].ct + b[i].ct;
 75                 if (a[lll].st + b[i].ct<X || a[lll].st>Tb + X)a[lll].et = a[lll].st;
 76             }
 77         }
 78         for (i = 1; i <= m; i++)
 79         {
 80             scanf("%d%d%d", &b[i].st, &b[i].ct, &b[i].d);
 81             b[i].et = b[i].st + b[i].ct;
 82             sum += b[i].d;
 83             a[++lll].st = b[i].et;
 84             j = Tb + X - a[lll].st;
 85             j = j % (2 * b[i].ct);
 86             a[lll].et = Tb + X - j;
 87             a[lll].d = b[i].d;
 88             if (j >= b[i].ct)a[lll].et += b[i].ct + b[i].ct;
 89             if (a[lll].st + b[i].ct<X || a[lll].st>Tb + X)a[lll].et = a[lll].st;
 90         }
 91         sort(a + 1, a + lll + 1, cmp);
 92         priority_queue<int, vector<int>, cmp1>q;
 93 
 94         for (i = 1; i <= lll; i++)
 95         {
 96             q.push(i); y = a[i].et;
 97             sum -= a[i].d;
 98             x = q.top();
 99             while (y - a[x].st > Ta && !q.empty())
100             {
101                 sum += a[x].d;
102                 q.pop(); x = q.top();
103             }
104             ans = min(ans, sum);
105         }
106         printf("%d\n", ans);
107     }
108     return 0;
109 }

 

posted @ 2016-11-17 13:29  demianzhang  阅读(336)  评论(0编辑  收藏  举报