1033 To Fill or Not to Fill (25分)

好几天没做题了...这一道题用的是贪心。贪心是一种思路,每一步都要做到最优,一步步实现局部最优,从而实现整体最优。思路参考了算法笔记。(设终点是油价为0,距离起点为dis的车站,)
1.当前车站为now,下一车站为next。next挑选策略为:在当前车站加满油可以到达的所有车站里找next。next为“当前车站加满油可以到达的所有车站里油价最低的”。
2.如果now的油价比next低,则在当前车站加满油前往next;如果now的油价比next高,则将油加到可以到达next的量即可(如果不需要加油就可以到达是最好)。不断更新now和next。
3.如果第一个车站距离起点不是0或者在当前车站加满油也到不了下一个车站,要及时结束算法。
1 #include <iostream> 2 #include<cstdio> 3 #include<vector> 4 #include<algorithm> 5 using namespace std; 6 struct STA{ 7 double pp,dd; 8 }; 9 bool cmp(STA x,STA y){ 10 return x.dd<y.dd; 11 } 12 13 14 vector<STA> sta(520); 15 int N; 16 double capacity,dis,D_average; 17 int now=0;//当前加油站编号 18 double Left=0;//油箱内的已有的油量 19 double total=0; 20 21 22 int findMin(int begin){ 23 int min=begin; 24 for(int i=begin;i<N+1;i++){ 25 if(sta[begin-1].pp>sta[i].pp&&(sta[i].dd-sta[now].dd)/D_average<=capacity) { 26 min=i; 27 break; 28 } 29 } 30 return min; 31 } 32 int main() 33 { 34 scanf("%lf%lf%lf%d",&capacity,&dis,&D_average,&N); 35 for(int i=0;i<N;i++){ 36 scanf("%lf%lf",&sta[i].pp,&sta[i].dd); 37 } 38 sta[N].pp=0; 39 sta[N].dd=dis; 40 sta.resize(N+1); 41 sort(sta.begin(),sta.end(),cmp); 42 if(sta[0].dd!=0){ 43 printf("The maximum travel distance = 0.00"); 44 return 0; 45 } 46 while(now<N){ 47 int next=findMin(now+1); 48 double need=(sta[next].dd-sta[now].dd)/D_average; 49 if(need>capacity){ 50 printf("The maximum travel distance = %.2f",sta[now].dd+capacity*D_average) ; 51 return 0; 52 } 53 if(sta[next].pp>sta[now].pp){//如果当前是最便宜的加油站,加满 54 total+=(capacity-Left)*sta[now].pp; 55 Left= capacity-need; 56 now=next; 57 } 58 else{//如果当前不是最便宜的加油站,把油量加至可以到达next 59 if(need>=Left) //如果left小于等于需要的油量 60 { 61 total+=(need-Left)*sta[now].pp; 62 now=next; 63 Left=0; 64 } 65 else{//如果left大于需要的油量 66 Left-=need; 67 now=next; 68 } 69 } 70 } 71 printf("%.2f",total); 72 return 0; 73 }

浙公网安备 33010602011771号