您的位置:首页 > 其它

ZOJ 3699 Dakar Rally(贪心)

2015-08-20 14:44 218 查看
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3699

Dakar Rally

Time Limit: 2 Seconds Memory Limit:65536 KB

Description

The Dakar Rally is an annual Dakar Series rally raid type of off-road race, organized by the Amaury Sport Organization. The off-road endurance race consists of a series of routes. In different routes, the competitors
cross dunes, mud, camel grass, rocks, erg and so on.

Because of the various circumstances, the mileages consume of the car and the prices of gas vary from each other. Please help the competitors to minimize their payment on gas.

Assume that the car begins with an empty tank and each gas station has infinite gas. The racers need to finish all the routes in order as the test case descripts.

Input

There are multiple test cases. The first line of input contains an integerT (T ≤ 50) indicating the number of test cases. ThenT test cases follow.

The first line of each case contains two integers:n -- amount of routes in the race;capacity -- the capacity of the tank.

The following n lines contain three integers each:mileagei -- the mileage of theith route;consumei -- the mileage consume of the car in theith
route , which means the number of gas unit the car consumes in 1 mile; pricei -- the price of unit gas in the gas station which locates at the beginning of theith route.

All integers are positive and no more than 105.

Output

For each test case, print the minimal cost to finish all of then routes. If it's impossible, print "Impossible" (without the quotes).

Sample Input

2
2 30
5 6 9
4 7 10
2 30
5 6 9
4 8 10

Sample Output

550
Impossible


题目大意:为赛车手安排个加油计划,使其骑完所有路线所耗费最少的由钱,当然如果中途因为油不够就输出Impossible表示完成不了。第一行T表示样例个数,紧接一行N,M,N表示有这么多条路,M代表车子油箱的容纳量。以后每行分别有三个数,表示改路线长度Len ,需要消耗的油量gas,该路段加油站的油价price.求出走完所有路线最低消费。

  

解题思路:使用贪心思路。是全称用的油价降到最低。显然赛车手是按顺序完成各个路线的,所以我们只需要考虑如何加油。加油就两种情况:1)假设在i点加油,直到将油使用完都找不到i点油价还便宜的,那么油加满,直到用完。2)如果油还没用完就能在j找到更低费用的油,那么只要加能到达j点的油量。注:起步时油箱是空的,要保证到达终点油刚好使用完。

复杂度分析:时间复杂度 :o(n*n)

空间复杂度 :o(n)

<span style="font-size:18px;">#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef long long LL;
const int maxn=100010;
int len[maxn],gas[maxn],price[maxn];
int main()
{
    int N;
    LL n,v;
    scanf("%d",&N);
    while(N--)
    {
        int flag=0;//用于表示,如果不能完成某条路线就标记1
        scanf("%lld %lld",&n,&v);
        for(int i=0;i<n;i++)
        {
            scanf("%lld %lld %lld",&len[i],&gas[i],&price[i]);
            if(len[i]*gas[i]>v)
                flag=1;
        }
        if(flag){
            printf("Impossible\n");
            continue;
        }
        int i=0;
        int j;
        LL r=0,t,ans=0;//r记录前一次加油加油前油箱剩余油量,ans为最低费用
        while(i<n)
        {
            j = i+1;//是按顺序完成路线的
            t=len[i]*gas[i];//完成i路线需要消耗的油量
            while(j<n && price[j]>=price[i] && v-t>=gas[j]*len[j])//如果还没找到更低的油价,且还能到达
                                                                   下一个站
            {
                t +=len[j]*gas[j];//到达下一次加油前消耗的油量和
                ++j;
            }
            if(j>=n || price[j]<price[i])//找到油价更低的加油站
            {
                if(r>t) r-=t;//如果之前剩余的油量有够直接减去消耗的,该站油价更低,在这站补充
                else{
                    ans+=(t-r)*price[i];//剩余油量不够,那就在上一次加油时加个刚好到达该站
                    r=0;
                }
                i=j;
            }
            else
            {
                ans+=(v-r)*price[i];//如果直到用完油都没找到低油价,就在上一次加到满
                r=v-len[i]*gas[i];//剩余的油量
                i++;
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: