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

 

 

posted @ 2013-06-02 18:41  E_star  阅读(219)  评论(0编辑  收藏  举报