【NOIP2011】觀光公交


題解:貪心策略----使用一次加速器,只會對當前第i站車上的乘客以及已經到第i+1站的乘客做出貢獻,每次貪心尋找到最優的站台加速即可。

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
#include<set>
#include<cstring>
#include<queue>
#include<stack>
#define MAXN 200010
#define LL long long int
using namespace std;
const int INF=1e9;
const int EPS=1e-8;
struct node{
    int T;
    int A;
    int B;
}a[MAXN];
int n,m,k;
int ans;
int d[MAXN];//從i到i+1的時間
int t[MAXN];//到達i的時刻
int f[MAXN];//最晚到達i的乘客的時刻
int g[MAXN];//在i車站加速最大影響到的車站
int sum[MAXN];//前i個車站下車的人數
int main()
{
    freopen("1.in","r",stdin);
    //    freopen("1.out","w",stdout);
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=n-1;i++)
        scanf("%d",&d[i]);
    for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&a[i].T,&a[i].A,&a[i].B);
            f[a[i].A]=max(f[a[i].A],a[i].T);//求出最晚到的乘客時刻
            sum[a[i].B]++;
        }
    for(int i=2;i<=n;i++)
        sum[i]+=sum[i-1];//前綴和求人數
    t[1]=0;
    for(int i=2;i<=n;i++)
        t[i]=max(t[i-1],f[i-1])+d[i-1];//當前到達i的時刻
    for(int i=1;i<=m;i++)
        ans+=t[a[i].B]-a[i].T;//旅游時間
    while(k>0)
        {
            g[n]=n;
            g[n-1]=n;
            for(int i=n-2;i;i--)
                {
                    if(t[i+1]<=f[i+1])//如果下一站的需要等待的乘客到達時間大於到達的時刻,那么在i+1車站之后站下車的乘客不會收到在i加速的影響
                        g[i]=i+1;
                    else g[i]=g[i+1];
                }
            int maxl=0,j;
            for(int i=1;i<=n;i++)
                if(sum[g[i]]-sum[i]>maxl&&d[i]>0)//找到影響最多人的車站,貪心策略
                    maxl=sum[g[i]]-sum[i],j=i;
            if(!maxl) break;
            ans-=maxl;
            d[j]--;//加速
            k--;//少了一個
            t[1]=0;
            for(int i=2;i<=n;i++)
                t[i]=max(t[i-1],f[i-1])+d[i-1];//再次貪心
        }
    cout<<ans<<endl;
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM