[搬運] [貪心]NOIP2011 觀光公交
阿新 • • 發佈:2017-10-08
end ber main endif bsp using .cn contain 即使
推薦這篇題解:http://www.cnblogs.com/Blacko/archive/2013/10/18/3376597.html
只不過這篇題解有一些細節沒有說清,但建議自己思考~
Codes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1010,M=10010;
int D[N];
ll up[N],leave[N],upt[N];
ll sum[N],f[N];
struct Passenger{
int s,e;
ll t;
}p[M];
ll endt[N];
int n,m,k;
inline ll conc( bool spdup){
int nt,np;
nt=np=0;
ll eff=-0x7fffffff,idx=-1,ne;
//計算endt
for ( int i=1;i<=n;i++){ endt[i]=max(endt[i-1],upt[i-1])+D[i-1]; } //計算f for(int i=n-1;i>=1;i--)f[i]=(upt[i+1]>=endt[i+1]?1:f[i+1]+1);
//計算eff
for ( int i=1;i<=n;i++){ if (!D[i]) continue ; ne=sum[f[i]+i]-sum[i]; if (ne>eff)eff=ne,idx=i;
}
if (spdup)D[idx]--;
else {
nt=0;
for ( int i=1;i<=m;i++)
nt+=endt[p[i].e]-p[i].t; return nt;
}
return 0;
}
int main(){
#ifdef LOCAL
freopen ( "bus.in" , "r" ,stdin);
freopen ( "bus.out" , "w" ,stdout);
#endif
scanf ( "%d%d%d" ,&n,&m,&k);
for ( int i=1;i<=n-1;i++){
scanf ( "%d" ,&D[i]);
}
ll t,u,l;
for ( int i=1;i<=m;i++){
scanf ( "%lld%lld%lld" ,&t,&u,&l);
upt[u]=max(upt[u],t);
up[u]++;
leave[l]++;
p[i].s=u,p[i].e=l,p[i].t=t;
}
//計算sum
for ( int i=1;i<=n;i++)sum[i]=sum[i-1]+leave[i];
for ( int i=1;i<=k;i++){
conc( true );
}
printf ( "%lld\n" ,conc( false ));
return 0;
}
|
Solution:
兩點需要註意的地方(按上方題解提供的數組含義來寫):
1.f[i]的推導。我一開始以為是若last[i+1]>time[i+1]則為0,得到的結果比答案大一點點……然後稍微魔改成了last[i+1]>=time[i+1]則為1,就tm對了……想了一下,可能是因為即使下一個站需要等待,這一個站至少能影響到第二個站;以及為什麽是last[i+1]>=time[i+1]而非last[i+1]>time[i+1]——當last[i+1]==time[i+1]時,此時time[i+1]再減少,下一個站仍然會變成需要等待,所以也對後方沒有影響,所以last[i+1]>=time[i+1]才是正確的範圍。
2.當一條邊已經被加速到0時,不能再加速。
其它看上面的題解和我的代碼吧2333
[搬運] [貪心]NOIP2011 觀光公交