sdut 2168 Mathmen 优先队列处理区间问题

题意:

给你n个地点的位置,他们是从小到大的顺序,然后每个位置都会有m个飞船,每个飞船能够传送一定的距离,如果使用该飞船会消耗掉一定的IQ,问如果一个人从1号位置开始选择飞船到达n号位置,最少的IQ花费是多少?

思路:

对于i位置与i+1位置,我们只要找出m个飞船中传送距离ds大于x[i + 1] - x[i]的花费IQ最少的即可。可是如何维护大于x[i + 1] - x[i]这个区间的里面最小的IQ消耗呢? 首先将相邻两点的距离求出来,然后从大到小排序,然后将m个飞船的创送距离从大到小排序,然后每次枚举到相邻两点之间的距离时,然后检查没有放入优先队列的可能比当前点的距离大的飞船,然后放进去,这样就能保证维护大于该距离的飞船的最IQ了。

#include <iostream>

#include <cstdio>

#include <cmath>

#include <vector>

#include <cstring>

#include <algorithm>

#include <string>

#include <set>

#include <functional>

#include <numeric>

#include <sstream>

#include <stack>

#include <map>

#include <queue>



#define CL(arr, val) memset(arr, val, sizeof(arr))



#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define ll long long

#define L(x)    (x) << 1

#define R(x)    (x) << 1 | 1

#define MID(l, r)   (l + r) >> 1

#define Min(x, y)   (x) < (y) ? (x) : (y)

#define Max(x, y)   (x) < (y) ? (y) : (x)

#define E(x)        (1 << (x))

#define iabs(x)     (x) < 0 ? -(x) : (x)

#define OUT(x)  printf("%I64d\n", x)

#define lowbit(x)   (x)&(-x)

#define Read()  freopen("data.in", "r", stdin)

#define Write() freopen("d.out", "w", stdout)





#define M 100007

#define N 10004



using namespace std;





const int inf = 0x7f7f7f7f;

const int mod = 1000000007;



struct node

{

    ll ds;

    ll iq;

    bool operator < (const node &a) const

    {

        return iq > a.iq;

    }

}nd[M],tmp;



ll dis[N],x[N];

int n,m;

priority_queue<node> pQ;



int cmp(node a,node b)

{

    if (a.ds != b.ds) return a.ds > b.ds;

    else return a.iq < b.iq;

}

int cmpx(int a,int b) { return a > b; }



int main()

{

//    Read();

    int T,i,j;

    scanf("%d",&T);

    while (T--)

    {

        scanf("%d%d",&n,&m);



        while (!pQ.empty()) pQ.pop();



        for (i = 1; i <= n; ++i) scanf("%lld",&x[i]);

        for (i = 1; i < n; ++i) dis[i] = x[i + 1] - x[i];

        sort(dis + 1,dis + n,cmpx);



        for (i = 1; i <= m; ++i) scanf("%lld%lld",&nd[i].ds,&nd[i].iq);



        sort(nd + 1,nd + 1 + m,cmp);



        ll ans = 0;



        int left = 1;    bool flag = false;

        for (i = 1; i < n; ++i)

        {

            ll dc = dis[i];

            for (j = left; j <= m; ++j)

            {

                left = j;

                if (nd[j].ds < dc) break;

                pQ.push(nd[j]);

            }

            if (pQ.empty())

            {

                flag = true;

                break;

            }

            ans += pQ.top().iq;

        }

        if (flag) printf("Impossible\n");

        else printf("%lld\n",ans);

    }

    return 0;

}
View Code

 

 

你可能感兴趣的:(Math)