http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3699
Dakar Rally Time Limit: 2 Seconds Memory Limit:65536 KBThe 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.
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.
For each test case, print the minimal cost to finish all of then routes. If it's impossible, print "Impossible" (without the quotes).
2
2 30
5 6 9
4 7 10
2 30
5 6 9
4 8 10
550
Impossible
复杂度分析:时间复杂度 :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>