Uva--10201(动规)

2014-08-05 00:14:22

2014-08-05 00:02:00

Problem A: Adventures in Moving - Part IV

To help you move from Waterloo to the big city, you are considering renting a moving truck. Gas prices being so high these days, you want to know how much the gas for such a beast will set you back.

The truck consumes a full litre of gas for each kilometre it travels. It has a 200 litre gas tank. When you rent the truck in Waterloo, the tank is half full. When you return it in the big city, the tank must be at least half full, or you'll get gouged even more for gas by the rental company. You would like to spend as little as possible on gas, but you don't want to run out along the way.

Input

The input begins with a single positive integer on a line by itself indicating the number of the cases following, each of them as described below. This line is followed by a blank line, and there is also a blank line between two consecutive inputs. 

Input is all integers. The first integer is the distance in kilometres from Waterloo to the big city, at most 10000. Next comes a set of up to 100 gas station specifications, describing all the gas stations along your route, in non-decreasing order by distance. Each specification consists of the distance in kilometres of the gas station from Waterloo, and the price of a litre of gas at the gas station, in tenths of a cent, at most 2000.

Output

For each test case, the output must follow the description below. The outputs of two consecutive cases will be separated by a blank line. 

Output is the minimum amount of money that you can spend on gas to get you from Waterloo to the big city. If it is not possible to get from Waterloo to the big city subject to the constraints above, print "Impossible".

Sample Input

1

500
100 999
150 888
200 777
300 999
400 1009
450 1019
500 1399

Output for Sample Input

450550

思路:递推DP,枚举到当前某个加油站所加的油量 v ,所以需要从之前一个加油站出发时的油量 vpre 来求得到当前加油站时的油量 vpre - distance,那么从当前加油站出发时
的油量为 vpre - distance + v,这样能算出加油费用。dp[pos][j]表示到第 pos 个加油站 剩油为 j 所需的最小费用,这样需要把第 0 个加油站设为起点,最后一个加油站设为终点。
(关于这题加油站的距离会不会超过目的地的问题,经过本人尝试,考不考虑这个问题均可AC,Uva测试数据中应该没有出现加油站距离超过目的地的情况)
 1 /*************************************************************************
 2     > File Name: h.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com
 5     > Created Time: Sun 03 Aug 2014 10:33:15 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 #define ll long long
16 
17 int t;
18 int tar;
19 ll dp[105][205];
20 char s1[20],s2[20];
21 int d[105],p[105];
22 int cnt;
23 
24 void Solve(){
25     for(int i = 0; i < cnt; ++i)
26         for(int j = 0; j <= 200; ++j)
27             dp[i][j] = 1e9;
28     dp[0][100] = 0;
29     for(int pos = 1; pos < cnt - 1; ++pos){
30         int dis = d[pos] - d[pos - 1];
31         for(int i = 0; i + dis <= 200; ++i)
32             if(dp[pos - 1][i + dis] != 1e9)
33                 for(int j = i; j <= 200; ++j)
34                     if(dp[pos - 1][i + dis] + (j - i) * p[pos] < dp[pos][j])
35                         dp[pos][j] = dp[pos - 1][i + dis] + (j - i) * p[pos];
36     }
37     ll ansmin = 1e9;
38     int dis = abs(d[cnt - 1] - d[cnt - 2]);
39     for(int i = 100; i + dis <= 200; ++i)
40         if(dp[cnt - 2][i + dis] != 1e9)
41             ansmin = min(ansmin,dp[cnt - 2][i + dis]);
42     if(ansmin >= 1e9)
43         printf("Impossible\n");
44     else
45         printf("%lld\n",ansmin);
46 }
47 
48 int main(){
49     //freopen("in","r",stdin);
50     scanf("%d",&t);
51     getchar();
52     while(t--){
53         cnt = 1;
54         scanf("%d",&tar);
55         getchar();
56         while(gets(s1) && s1[0] != '\0'){
57             int tpos = strchr(s1,' ') - s1;
58             s1[tpos] = '\0';
59             d[cnt] = atoi(s1);
60             p[cnt++] = atoi(s1 + tpos + 1);
61         }
62         d[cnt] = tar;
63         p[cnt++] = 0;
64         Solve();
65         if(t)   printf("\n");
66     }
67     return 0;
68 }

 

转载于:https://www.cnblogs.com/naturepengchen/articles/3891339.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值