其他分享
首页 > 其他分享> > P1315 观光公交(贪心)

P1315 观光公交(贪心)

作者:互联网

题目描述

N个车站,M个人,每个人有一个起始车站,一个结束车站,一个到达起始车站的时间。第i个车站到下一个车站的距离为di,有k个加速器,每个可以使任意两个相邻车站的距离减小1。问该如何安排使用加速器,才能使所有乘客的旅行时间总和最小?

思路

每个车站最先到达的人一定要等到最后一个到达的人到达才能出发,所以这段时间没法优化。预处理出每个车站的信息,然后k次查找优化后贡献最大的方案,进行优化,维护该区间后车站的信息。

可以优化的东西有:每个车站乘客的上车时间(人不用等车为最优)、每个乘客到达目标车站的时间(尽可能用时短)

 

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
#include <map>
#include <cstdlib>
#include <ctime>
using namespace std;
#define ll long long
#define ull unsigned long long
#define ld long double
#define lowbit(x) ((x) & (-x))
#define For(x, i, j) for (ll x = (i); x <= (j); x++)
#define FOR(x, i, j) for (ll x = (i); x >= (j); x--)
#define ls(o) (o << 1)
#define rs(o) (o << 1 | 1)
#define debug(x) cout << "debug : " << x << endl;
inline ll read(){
   ll s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}
#define N 1005
#define M 10005
#define K 100005
ll n, m, k, ans;
ll d[N];
struct ps {
    ll st, ed;
    //st:这个乘客开始等车的时刻 
    //ed:这个乘客最终要到达的车站 
} p[K];
struct station {
    ll arrive, latest, off;
    //arrive:车到该站的时刻 
    //latest:在该站上车的人中,最晚上车的人的上车时刻 
    //off:在该站下车的人数 
} s[N];
int main() {
    n = read(), m = read(), k = read(); For(i, 1, n - 1) d[i] = read();
    For(i, 1, m) {ll t; p[i].st = read(); t = read(); p[i].ed = read();
        s[t].latest = max(s[t].latest, p[i].st);
        s[p[i].ed].off++;
    }
    ll time = 0;//时钟 
    For(i, 1, n) {
        s[i].arrive = time;
        time = max(time, s[i].latest);//取max的原因:可能是人等车,也可能是车等人 
        time += d[i]; 
    }
    ll max_num, max_pos, tmp_num;
    while (k--) {
        max_num = 0;
        For(i, 2, n) {//每次找一个优化后ans减少最大的区间 
            if (!d[i - 1]) continue;//这段路已经优化光了 
            tmp_num = 0;
            For(j, i, n) {
                tmp_num += s[j].off;
                if (s[j].arrive <= s[j].latest) break;//已经优化到需要车等人了 
            }
            if (tmp_num > max_num) {
                max_num = tmp_num;
                max_pos = i;
            }
        }
        d[max_pos - 1]--;
        For(i, max_pos, n) {
            s[i].arrive--;
            if (s[i].arrive < s[i].latest) break;
        }
    }
    For(i, 1, m) {ans += s[p[i].ed].arrive - p[i].st;}
    printf("%lld\n", ans);
    return 0;
} 

 

标签:贪心,ch,车站,观光,long,P1315,max,include,define
来源: https://www.cnblogs.com/FL4K/p/14074824.html