vijos1741 观光公交 (贪心)
|
大意:题目说得很清楚,我都怕。
题解:贪心,一个个选择氮气加速的位置。
首先我们看乘客所花时间和怎么计算,容易得到一个乘客所花的时间等于
ar[b[i]] - T[i]
其中b[i]为该乘客的终点,ar[x]为到达x站的时间,T[i]为该乘客出发的时间。
我们把到达x的乘客统计,cntto[x]为到达x的乘客的数量,然后所有乘客所花的时间和,就是sum(cntto[i]*ar[i])-sumT,cntto和sum都是已知的,关键在于ar。
设st[i]为从i出发的最晚一名游客的出现时间,这样我们可以用st[i]和d[i]来从头到尾得到各个点的ar[i]。
for(i=1; i<n; i++) artime[i]=max(artime[i-1],st[i-1])+d[i-1];
然后我们一个个氮气加速分别考虑,每次贪心放在能减少时间总和最多的位置。对每个位置计算,向后推若干个ar[i]>st[i],即有发展潜力的位置,(若ar[i]<=st[i],则减少ar[i]也无法减少之后游客的时间)。
1 for(i=0; i<n-1; i++) { 2 if(d[i]>0) { 3 canup=cntto[i+1]; 4 j=i+1; 5 while(j+1<n && artime[j]>st[j])canup+=cntto[j+1],j++; 6 //cout<<i<<','<<j<<endl; 7 if(canup>maxup) { 8 maxup=canup; 9 maxi=i; 10 } 11 } 12 }
这样我们就在maxi处氮气加速,效果最碉。
重复多次,用完所有氮气加速,完成。
1 //#pragma comment(linker, "/STACK:102400000,102400000") 2 #include<cstdio> 3 #include<cmath> 4 #include<iostream> 5 #include<cstring> 6 #include<algorithm> 7 #include<cmath> 8 #include<map> 9 #include<set> 10 #include<stack> 11 #include<queue> 12 using namespace std; 13 #define ll long long 14 #define usint unsigned int 15 #define mz(array) memset(array, 0, sizeof(array)) 16 #define minf(array) memset(array, 0x3f, sizeof(array)) 17 #define REP(i,n) for(i=0;i<(n);i++) 18 #define FOR(i,x,n) for(i=(x);i<=(n);i++) 19 #define RD(x) scanf("%d",&x) 20 #define RD2(x,y) scanf("%d%d",&x,&y) 21 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z) 22 #define WN(x) printf("%d\n",x); 23 #define RE freopen("D.in","r",stdin) 24 #define WE freopen("1biao.out","w",stdout) 25 26 const int maxn=1111; 27 const int maxm=11111; 28 int d[maxn],T[maxm],a[maxm],b[maxm]; 29 int st[maxn],artime[maxn]; 30 int cntto[maxn]; 31 int canup[maxn]; 32 int n,m,k; 33 ll Tsum; 34 35 int main() { 36 int i,j; 37 int maxi,maxup,canup; 38 ll ans; 39 while(scanf("%d%d%d",&n,&m,&k)!=EOF) { 40 REP(i,n-1) scanf("%d",&d[i]); 41 mz(st); 42 mz(cntto); 43 Tsum=0; 44 REP(i,m) { 45 scanf("%d%d%d",&T[i],&a[i],&b[i]); 46 a[i]--;b[i]--; 47 if(st[a[i]]<T[i])st[a[i]]=T[i]; 48 cntto[b[i]]++; 49 Tsum+=T[i]; 50 } 51 artime[0]=0; 52 for(i=1; i<n; i++) artime[i]=max(artime[i-1],st[i-1])+d[i-1]; 53 while(k>0) { 54 maxi=-1; 55 maxup=-1; 56 for(i=0; i<n-1; i++) { 57 if(d[i]>0) { 58 canup=cntto[i+1]; 59 j=i+1; 60 while(j+1<n && artime[j]>st[j])canup+=cntto[j+1],j++; 61 //cout<<i<<','<<j<<endl; 62 if(canup>maxup) { 63 maxup=canup; 64 maxi=i; 65 } 66 } 67 } 68 d[maxi]--; 69 //printf("WOW,%d!",maxi); 70 artime[0]=0; 71 k--; 72 for(i=1; i<n; i++) artime[i]=max(artime[i-1],st[i-1])+d[i-1]; 73 } 74 ans=-Tsum; 75 for(i=1; i<n; i++) 76 ans+=artime[i]*cntto[i]; 77 printf("%lld\n",ans); 78 } 79 return 0; 80 }