Mathmen 优先队列贪心

Problem Description

Mathmen love mathematics, and they live on the number line. All the mathmen spend all their time on solving mathematical problems and proving theorems. Like humen beings, mathmen don't live in the same country there are n mathmen countries on difierent positions of the number line (country i lives at position xi (one point on the number line), and xi < xi + 1 for all 1 <= i <= n - 1). Mathmen in difierent countries are good at difierent areas of mathematics. For example, mathmen living in country 1 are good at geometry, while mathmen living in country 2 are experts on algebra.

Lately, all the mathmen nations have collaborated on a huge problem, which involves all areas of mathematics, and each mathmen country is responsible for solving the part they are good at. After hours of work (they are really good at mathematics, and no problem would cost them more than one day to solve), they all finish their jobs. Now, they need to collect the result in every mathmen country, and combine them together to create the solution to the huge problem. So they decide to let one mathman collect all the results and send it to one country, where all the work will be merged.

As mathmen are devoted to solving mathematical problems, their legs has become very weak after millions of years of evolution. Therefore, they have to ride mathships to travel on the number line. Their are M types of mathships, each of which has a limit of traveling distance and a cost of IQ (yes, you need to be very brave to take mathships, you would never be able to get back the lost IQ).

There are two seasons in the mathmen world Positive and Negative. Now it is Positive, so all the mathships travels on the number line from left to right. Therefore, one man from country 1 must be selected as the volunteer to collect the results in every country and send to to country n.

There is at least one mathship of each type in every country. So, after picking the results from country 1, the volunteer needs to select one mathship with a limit of traveling distance at least the distance between country 1 and country 2 (the distance is x2 - x1), and ride it from country 1 to country 2.

Meahwhile, this trip will cost him the corresponding amount of IQ. Then, he picks the result from country 2, choose another suitable mathship (the old mathship will be maintained in country 2, and can not continue to be used), and ride it to country 3, and lose some IQ. He will repeat this process, until he reaches country n.

Mathmen care about their IQ a lot, so the volunteer wants to minimize the total cost of his IQ. Could you please write program to help him select the right mathships to take?

Input
The input contains multiple test cases. The first line of the input is an integer  C, indicating the number of test cases in the input.

Each test case begins with a line containing two integers, n (2 <= n <= 10000) and m (1 <= m <= 100000), which is the number of mathmen countries and the number of mathship types. The next line contains n integers, ranging from -10^9to10^9(inclusive), indicating the positions of the mathmen countries. Then, m lines follows, each containing two non-negative integers no more than 2*109, which are the limit of traveling distance and the cost of IQ.

Output
  For each test case, output one line containing the minimum cost of IQ. If the  volunteer can never reach country n, output "Impossible" (without quotation  marks).
Sample Input
2
3 3
0 3 10
1 0
6 1
10 10
2 1
0 1000
100 0
Sample Output
11
Impossible
Hint
 
Source

山东省第二届ACM大学生程序设计竞赛 




对于每一个间隔,我们是选择能到达的工具中花费最少的。我们不需要重复计算,因为能到达远的工具,近的一定也能到达。

这是一个优化点。

所以我们把间隔求出来,从大到小排序。再把所有工具从大到小排序。

对于当前间隔,我们看看剩余的工具有没有能到达的,把能到达的放到队列中,队列中还有能到达当前距离更远的距离的工具。

在这所有的工具中,我们选择花费最小的即可。优先队列处理

#include <iostream>
#include <string.h>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;


priority_queue<long long,vector<long long>,greater<long long> >que;
struct node
{
    long long juli;
    long long cost;
}jiaotong[1100000];
bool cmp(node t1,node t2)
{
    return t1.juli<t2.juli;
}
long long a[1100000];
long long cha[1100000];
int n,m;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        while(!que.empty())
        {
            que.pop();
        }
        cin>>n>>m;
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
            if(i!=0)
            {
                cha[i]=a[i]-a[i-1];
            }
        }
        for(int i=0;i<m;i++)
        {
            cin>>jiaotong[i].juli>>jiaotong[i].cost;
        }
        sort(cha+1,cha+n);
        sort(jiaotong,jiaotong+m,cmp);
        int j=m-1;
        int flag=0;
        long long ans=0;
        for(int i=n-1;i>=1;i--)
        {
            while(j>=0)
            {
                if(jiaotong[j].juli>=cha[i])
                {
                    que.push(jiaotong[j].cost);
                    j--;
                }
                else
                {
                    break;
                }
            }


            if(que.empty())
            {
                flag=1;
                break;
            }
            ans+=que.top();
       
        }
        if(flag)
        {
            cout<<"Impossible"<<endl;
        }
        else
        cout<<ans<<endl;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值