一.题目链接:
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;
}