一.题目链接:

Mathmen

二.题目大意:

题目长的让人绝望

有 n 个城市,给出这 n 个城市的位置.

每个城市都有 m 种船.

每种船有相应的最大里程 和 花费.

一个人从第一个城市出发,坐船去往其他城市,每到一个城市就要换一条船.

问最少花费是多少.

三.分析:

一开始没搞清楚关系,直接结构体排序 + 二分,然后成为了疯狂 WA 动机.

这题其实很水.

把相应的距离存起来 + 排序.

船存起来 + 结构体排序.

然后找就可以了(反着找).

因为如果 s[pos] 满足 dis[i],那么 s[pos] 也一定满足 dis[i - 1],所以开一个优先队列存结构体即可.

每次循环 ans 都加上优先队列顶部的花费.

四.代码实现:

#include <set>
#include <map>
#include <ctime>
#include <queue>
#include <cmath>
#include <stack>
#include <vector>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define eps 1e-4
#define PI acos(-1.0)
#define ll long long int
using namespace std;

const int M = (int)1e4 + 10;
ll a[M];
ll dis[M];
struct node
{
    ll dis;
    ll cost;
} s[M * 10];

bool cmp(node a, node b)
{
    if(a.dis == b.dis)
        return a.cost < b.cost;
    return a.dis < b.dis;
}

bool operator < (node a, node b)
{
    return a.cost > b.cost;
}

int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        int n, m;
        scanf("%d %d", &n, &m);
        for(int i = 0; i < n; ++i)
            scanf("%lld", &a[i]);
        for(int i = 1; i < n; ++i)
            dis[i] = a[i] - a[i - 1];
        sort(dis + 1, dis + n);
        for(int i = 0; i < m; ++i)
            scanf("%lld %lld", &s[i].dis, &s[i].cost);
        sort(s, s + m, cmp);
        if(dis[n - 1] > s[m - 1].dis)
        {
            printf("Impossible\n");
            continue;
        }
        ll ans = 0;
        priority_queue <node> q;
        int pos = m - 1;
        for(int i = n - 1; i >= 1; --i)
        {
            while(pos >= 0 && s[pos].dis >= dis[i])
            {
                q.push(s[pos]);
                pos--;
            }
            ans += q.top().cost;
        }
        printf("%lld\n", ans);
    }
    return 0;
}