1. 程式人生 > >ZOJ 3699 Dakar Rally

ZOJ 3699 Dakar Rally

minimal camel ans output sync 代碼 long long 找到 pts

鏈接: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 integer T (T ≤ 50) indicating the number of test cases. Then T 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 the ith route; consumei -- the mileage consume of the car in the ith 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 the ith route.

All integers are positive and no more than 105.


Output

For each test case, print the minimal cost to finish all of the n 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


Author: OUYANG, Jialin
Contest: The 13th Zhejiang University Programming Contest


大意——有一個越野拉力賽,賽程包含很多個賽段。

由於各種各樣的情況,所以汽車各賽段每英裏的耗油量和油價都不一樣。如今,給你每一個賽段的裏程。油耗量,油價以及油箱容量,請你幫助參賽者決策。以便盡量少花油費。

如果參賽者一開始汽車裏面沒有油。每一個加油站的油無限以及參賽者必須完畢全部賽段才算完畢任務。


思路——顯然這是一道貪心的題目。

那麽貪心策略是如何的呢?由於完畢各個賽段的順序一定,所以我們須要考慮該怎麽樣用油。

首先,假如某個賽段的總油耗量大於油箱容量。那麽參賽者是不可能完畢本賽段的,亦即不可能完畢任務。再者,要油費最少,那麽每次保證油箱裏面的油廉價的最多就可以了。最後,要考慮的就是在第i站要不要加油。怎麽加。加的有兩種情況出現:1.在第i點把油加滿,直到用完都沒能找到比i點價格廉價的,那麽果斷加滿。開到下一點去。2.在第i點把油加滿,沒用完之前可以找到比i點廉價的點,或者是到達終點,那麽僅僅要將油加到能到達這個點就可以,然後直接到達這個點。

最後,把每一個點所需油費加起來就可以。



復雜度分析——時間復雜度:O(n^2),空間復雜度:O(n)


附上AC代碼:


#include <iostream>
#include <cstdio>
#include <string>
#include <cmath>
#include <iomanip>
#include <ctime>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <set>
#include <map>
using namespace std;
typedef unsigned int UI;
typedef long long LL;
typedef unsigned long long ULL;
typedef long double LD;
const double pi = acos(-1.0);
const double e = exp(1.0);
const int maxn = 100005;
LL mileage[maxn], consume[maxn], price[maxn];
// 存儲每個賽段的長度,單位長度耗油量以及單位容量油價
int n; // 表示賽段的個數
LL capacity; // 坦克的容量

int main()
{
	ios::sync_with_stdio(false);
	int T; // 例子的個數
	scanf("%d", &T);
	while (T--)
	{
		bool flag = 0; // 標記是否達標,即每個賽段是否可以通過
		scanf("%d%lld", &n, &capacity);
		for (int i=0; i<n; i++)
		{
			scanf("%lld%lld%lld", &mileage[i], &consume[i], &price[i]);
			if (mileage[i]*consume[i] > capacity)
				flag = 1; // 賽段i耗油量大於存儲的油量,坦克不足以支撐到
						  // 下一個賽段,故不可能完畢全部賽段
		}
		if (flag)
		{ // 全部油耗盡都不能到達下一個賽段。則失敗
			printf("Impossible\n");
			continue;
		}
		LL min_price = 0; // 記錄最小花費
		LL extra = 0; // 記錄到達賽段i時坦克剩余油量
		for (int i=0; i<n;)
		{
			int j = i+1; // 從賽段i的下一個賽段開始尋找價格廉價的賽段
			int temp = mileage[i]*consume[i]; // 到達下一個廉價的賽段所須要的油量
			while (j<n && price[j]>=price[i] && capacity-temp>=mileage[j]*consume[j])
			{ // 向終點查找,直到找到一個比賽段i價格廉價的賽段j。或者是油耗盡了
				temp += mileage[j]*consume[j];
				j++;
			}
			if (j>=n || price[j]<price[i])
			{ // 找到賽段j的價格比賽段i廉價,僅僅要把油加到能到達賽段j就可以
				if (extra > temp) // 油非常多。不須要花錢買
					extra -= temp;
				else
				{
					min_price += (temp-extra)*price[i]; // 油不夠,僅僅需買能達到賽段j的油就可以
					extra = 0; // 油箱的油全部用完
				}
				i = j;
			}
			else
			{ // 油耗盡了都沒有找到比賽段i價格廉價的賽段
				min_price += (capacity-extra)*price[i]; // 加滿油,到下一個賽段
				extra = capacity-mileage[i]*consume[i]; // 到下一個賽段還剩多少油
				i++;
			}
		}
		printf("%lld\n", min_price);
	}
	return 0;
}


ZOJ 3699 Dakar Rally