标签:isp AC src 序列 double scan span onclick play
例题
[ 一 ] 旅行家的预算
题目:
具体思路如下:
1.如果不能到达,输出 -1
2.如果之后的序列中存在小于等于(注意取等号),找到第一个(证明:如果不是第一个最小值……),计算,加油到刚好到达目标点。
3.如果没有更小的,找到能到达的最小值,计算,加满油且没有越过终点。
代码见下:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 #include<cmath> 6 #include<algorithm> 7 using namespace std; 8 struct Sto { 9 double Pri; 10 double Dist; 11 } Pot[9]; 12 double Abt,v,Dist; 13 int n; 14 int main() { 15 scanf("%lf%lf%lf%lf%d",&Dist,&v,&Abt,&Pot[0].Pri,&n); 16 for(int i = 1; i<=n; i++) { 17 scanf("%lf%lf",&Pot[i].Dist,&Pot[i].Pri); 18 } 19 double Cost = 0,Now = 0; 20 int End = 0; 21 for(int i = 0; i<n; i++) { 22 if(Pot[i].Pri > Pot[i + 1].Pri) { 23 Cost += (Pot[i + 1].Dist - Now * Abt - Pot[i].Dist) * Pot[i].Pri / Abt; 24 End = i + 1; 25 Now = 0; 26 } else { 27 double Max = v * Abt; 28 if(Max < Pot[i + 1].Dist - Pot[End].Dist) { 29 printf("-1"); 30 return 0; 31 } else { 32 double Min = 1000; 33 int Idx = 0; 34 for(int j = i + 1; j<=n; j++) { 35 if(Pot[j].Dist - Pot[End].Dist > Max) { 36 break; 37 } 38 if(Pot[j].Pri <= Min) { 39 Min = Pot[j].Pri; 40 Idx = j; 41 if(Min <= Pot[End].Pri) { 42 break; 43 } 44 } 45 } 46 if(Min > Pot[End].Pri) { 47 Cost += (v - Now) * Pot[End].Pri; 48 Now = v - (Pot[Idx].Dist - Pot[End].Dist) / Abt; 49 if(Now * Abt >= Dist - Pot[Idx].Dist) { 50 Cost -= (Now * Abt - Dist + Pot[Idx].Dist) * Pot[End].Pri / Abt; 51 printf("%.2lf",Cost); 52 return 0; 53 } 54 } else { 55 Cost += (Pot[Idx].Dist - Now * Abt - Pot[End].Dist) * Pot[End].Pri / Abt; 56 Now = 0; 57 } 58 i = Idx - 1; 59 End = Idx; 60 } 61 } 62 } 63 Cost += max(0.0,(Dist - Pot[End].Dist - Now * Abt) * Pot[End].Pri / Abt); //可以不用max了,我前面已经return0了 64 printf("%.2lf",Cost); 65 return 0; 66 }
标签:isp AC src 序列 double scan span onclick play
原文地址:https://www.cnblogs.com/wenoi/p/GreedyMethod.html