Road to Cinema(貪心+二分)
阿新 • • 發佈:2018-07-08
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)
v≥x?2+l?x
x≥0l?x≥0(1)
{ t=x+2?(l?x)
v≥x?2+l?x
x≥0
l?x≥0
化簡一下:
t=2?l?x
x≤v?l
l≥x≥0(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 #definefi 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(貪心+二分)