/* 一眼就知道是贪心 关键是怎么贪 考虑到每个乘客的旅行时间只算在车上的 没想太多 一看是按照每一段路上的乘客数 乘客越多的 使用加速卡 然后自信的交了 10分..... */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 10010 using namespace std; int n,m,k,t[maxn],f[maxn],s[maxn],ans; struct node { int num,o,t; }p[maxn]; struct people { int ti,u,v; }peo[maxn]; int cmp(node x,node y) { return x.num>y.num; } int main() { //freopen("bus.in","r",stdin); //freopen("bus.out","w",stdout); scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n-1;i++) scanf("%d",&t[i]); int u,v,ti,pre; for(int i=1;i<=n;i++) p[i].o=i; for(int i=1;i<=m;i++) { scanf("%d%d%d",&ti,&u,&v); peo[i].ti=ti;peo[i].u=u;peo[i].v=v; s[u]=max(s[u],ti); for(int j=u;j<=v;j++)p[j].num++; } sort(p+1,p+1+n,cmp); pre=s[1]; for(int i=1;;i++) if(t[p[i].o]>=k) { t[p[i].o]-=k; break; } else k-=t[p[i].o],t[p[i].o]=0; for(int i=2;i<=n;i++) { f[i]=pre+t[i-1]; pre=max(pre+t[i-1],s[i]); } for(int i=1;i<=m;i++) ans+=f[peo[i].v]-peo[i].ti; printf("%d ",ans); return 0; }
/* 上面的思路不难发现问题 显然并没有考虑到每次出发必须等到人来全了 假设又一次我们承载着最多的人飞到了下一站 然而并没有几个人立刻下车 那么乘客还是要等人全了之后再走 时间没有少多少 显然贪心错误 下面说说正解(其实看到他是某年noip D2 T3就知道这么简单的贪心肯定会挂掉) 考虑到必须等人全了车才能走 所以我们每使用一个加速卡的时候会 影响到后面的好几次到站时间 然而并不是全部 我们要做的就是统计能影响到哪 没使用一个加速卡 我们就找这个影响的线段最长的 然后最开始那一段时间-- 更新后面的到站时间 同时更新每个点能影响到哪 那么这次加速节省的时间就是这一段下车人数*1 我们可以预先统计下没有加速的时候的时间 */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 10010 using namespace std; int n,m,k,t[maxn],f[maxn],s[maxn],ans,num[maxn],g[maxn]; struct people { int ti,u,v; }p[maxn]; void solve() { int maxx=0,l,r; for(int i=1;i<=n;i++) if(maxx<num[g[i]]-num[i]&&t[i]>0) { l=i;r=g[i]; maxx=num[g[i]]-num[i]; } t[l]--;if(r>n-1)r=n-1;ans-=maxx; for(int i=l;i<=r;i++) f[i]=max(f[i-1],s[i-1])+t[i-1]; for(int i=r;i>=l;i--) if(f[i+1]<=s[i+1])g[i]=i+1; else g[i]=g[i+1]; } int main() { //freopen("bus.in","r",stdin); //freopen("bus.out","w",stdout); scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n-1;i++) scanf("%d",&t[i]); int u,v,ti; for(int i=1;i<=m;i++) { scanf("%d%d%d",&ti,&u,&v); p[i].ti=ti;p[i].u=u;p[i].v=v; s[u]=max(s[u],ti);num[v]++; } for(int i=2;i<=n;i++)num[i]+=num[i-1]; for(int i=1;i<=n;i++) f[i]=max(f[i-1],s[i-1])+t[i-1]; g[n]=g[n-1]=n; for(int i=n-2;i>=1;i--) if(f[i+1]<=s[i+1])g[i]=i+1; else g[i]=g[i+1]; for(int i=1;i<=m;i++) ans+=f[p[i].v]-p[i].ti; for(int i=1;i<=k;i++) solve(); printf("%d ",ans); return 0; }