1. 程式人生 > >Road to Cinema(貪心+二分)

Road to Cinema(貪心+二分)

int -s 最長 blog for spl tex long long ssi

https://www.cnblogs.com/flipped/p/6083973.html 原博客轉載

http://codeforces.com/group/1EzrFFyOc0/contest/738/problem/C 題目鏈接

題意:n個價格c[i],油量v[i]的汽車,求最便宜的一輛使得能在t時間內到達s,路途中有k個位置在g[i]的加油站,可以免費加滿油,且不耗時間。每輛車有兩種運行模式可以隨時切換:1.每米一分鐘兩升油;2.每米兩分鐘一升油。

題解:二分求可以到達s的最小油量。對於油量v,能到達s的條件是:油量足夠經過最長路程(中途不能加油);總的最小時間不超過t。為了求最小時間,可以用線性規劃:一段不加油的路程長度為l,假設x米運行的是1.模式,則l-x米運行的是2.模式。總時間為t。則有

  t=x+2?(l?x)

  vx?2+l?x

  x0l?x0(1)

 { t=x+2?(l?x)

  v≥x?2+l?x

  x≥0

  l?x≥0

化簡一下:

  t=2?l?x

  xv?l

  lx0(2)

  {t=2?l?x

  x≤v?l

  l≥x≥0

最後得到:

  tmin=2?l?xmax   =2?l?min(v?l,l)   =max(l?3?v,l)tmin   =2?l?xmax   =2?l?min(v?l,l)   =max( l?3?v,l )

且v≥l,可以改為v≥max(l)。

 1 #include<iostream>
 2
#include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<set> 7 #include<vector> 8 #include<stack> 9 #include<queue> 10 #include<map> 11 using namespace std; 12 #define ll long long 13 #define se second 14 #define
fi first 15 const int Mos = 0x7FFFFFFF; //2147483647 16 const int nMos = 0x80000000; //-2147483648 17 const int N=2e5+5; 18 19 int n,k,s,t,dis; 20 int c[N],v[N],g[N]; 21 22 bool check(int vv) //油量 23 { 24 if(vv<dis) return 0; //如果開低速的油都不夠 25 int sumt=0; 26 for(int i=1;i<=k+1;i++) 27 { 28 sumt+= max(g[i],3*g[i]-vv); 29 if(sumt>t) return 0; //超出時間 30 } 31 return 1; 32 } 33 int main() 34 { 35 cin>>n>>k>>s>>t; 36 for(int i=1;i<=n;i++) scanf("%d%d",&c[i],&v[i]); 37 for(int i=1;i<=k;i++) scanf("%d",&g[i]); 38 g[k+1]=s; 39 sort(g+1,g+1+k); 40 for(int i=k+1;i>=1;i--) 41 dis=max(dis,g[i]-=g[i-1]); //找出加油站間最長間隔,順便把g[i]變為距離前面一個的距離 42 int l=0,r=1e9+5,mid,res=0; 43 while(l<=r) //二分找出最少需要的油量; 44 { 45 mid=(l+r)>>1; 46 if( check(mid) ) r=mid-1,res=mid; //記錄最優的res 47 else l=mid+1; 48 } 49 int ans=1e9+1; 50 if(res) 51 for(int i=1;i<=n;i++) 52 if(v[i]>=res) ans=min(ans,c[i]); 53 if(ans>=1e9+1) ans=-1; 54 55 cout<<ans<<endl; 56 }

Road to Cinema(貪心+二分)