【链接】h在这里写链接


【题意】


有n个人,它们都要在某一时刻开始,全都到达0位置,然后维持最少k个时间单位,然后再全都回到原来的位置;
第i个人初始的位置是i.
且一共有m班航班.
每一班航班,要么是从0出来的,要么是进入0的,且航班起飞的时间为di,出发地为fi,目的地为ti,花费为ci;
(航班当天到);
到或起飞的那一天不算k天中的一天。
问你每个人到达0,然后又回到各自位置的最小花费。

【题解】


考虑每个航班起飞的时间,把每个航班的信息加入到di时刻上.
vector <pair <int,int> >in[N];
存的是i时刻,进入0位置的飞机来自哪里,以及花费。
vector <pair <int,int> >out[N];
存的是i时刻,飞出0位置的飞机要到哪里,以及花费。
然后O(N)顺着扫和逆着扫两遍。
就能得到f1[i],num1[i];
f1[i]表示前i个位置,有num1[i]个人能到0位置,最小的花费是多少.
(时间顺序处理)
以及f2[i],num2[i];
f2[i]表示后n-i+1个位置,有num2[i]个人能回到原位置,最小的花费是多少;
(时间逆序处理就好)
以处理f1[i]为例。
进入i+1时刻的时候,看看i+1这个时间,有多少个航班到位置0,然后,看看某个人来0位置的花费能不能因此变少
(也即是不是那个人坐这班航班更优)
如果可以因此变少的话,f1[i]也能变少.
(如果那个人是第一次可以来0位置,那么num1[i]++)
用一个mi[N]来维护某个人到达0位置的最小花费就可以了。
(f2[i]用类似的方法维护就好)
然后枚举这n个人是何时开始全都到达0号位置的
f1[i]+f2[i+k+1]最小值就可以了;
(num1[i]和num2[i+k+1]都必须为n);

【错的次数】


0

【反思】


感觉很自然的思路。

【代码】

#include <bits/stdc++.h>
using namespace std; const int N = 1e6; int n, m, k;
vector <pair <int, int > > in[N + 10], out[N + 10];
long long f1[N + 10], f2[N + 10];
int num1[N + 10], num2[N + 10];
int mi[N + 10], MI[N + 10]; int main() {
    ios::sync_with_stdio(0), cin.tie(0);     cin >> n >> m >> k;
    for (int i = 1; i <= m; i++) {
        int d, f, t, c;
        cin >> d >> f >> t >> c;
        if (t == 0)
            in[d].push_back(make_pair(f, c));
        else {
            //f == 0
            out[d].push_back(make_pair(t, c));
        }
    }     for (int i = 1; i <= N; i++) {
        num1[i] = num1[i - 1];
        f1[i] = f1[i - 1];
        for (int j = 0; j <= (int)in[i].size() - 1; j++) {
            int from = in[i][j].first, cost = in[i][j].second;
            if (mi[from] == 0) {
                mi[from] = cost;
                num1[i]++;
                f1[i] += cost;
            }
            else {
                if (mi[from] > cost) {
                    f1[i] -= (mi[from] - cost);
                    mi[from] = cost;
                }
            }
        }
    }     for (int i = N; i >= 1; i--) {
        f2[i] = f2[i + 1];
        num2[i] = num2[i + 1];
        for (int j = 0; j <= (int)out[i].size() - 1; j++){
            int to = out[i][j].first; int cost = out[i][j].second;
            if (MI[to] == 0) {
                MI[to] = cost;
                f2[i] += cost;
                num2[i]++;
            }
            else {
                if (MI[to] > cost) {
                    f2[i] -= (MI[to] - cost);
                    MI[to] = cost;
                }
            }
        }
    }     long long ans = -1;
    for (int i = 1; i + k +1 <= N; i++)
        if (num1[i]==n){
            if (num2[i + k + 1] == n) {
                long long temp = f1[i] + f2[i + k + 1];
                if (ans == -1) {
                    ans = temp;
                }
                else
                    ans = min(ans, temp);
            }
        }
    cout << ans << endl;
    return 0;
}

【Codeforces Round #433 (Div. 1) B】Jury Meeting的更多相关文章

  1. 【Codeforces Round #433 (Div. 2) C】Planning

    [链接]h在这里写链接 [题意] 让你确定ti,使得∑(ti-i)*gi最小,其中ti∈[k+1..k+n],且每个ti都不能一样. 且ti>=i必须成立. [题解] 分解一下成为∑ti*gi ...

  2. 【Codeforces Round #433 (Div. 2) B】Maxim Buys an Apartment

    [链接]h在这里写链接 [题意] 你有n个位置,然后其中有k个地方是已经被人占据了的. 一个"好的位置"的定义是指,这个位置相邻的地方其中至少有一个被人占据了. k个被人占据的位置 ...

  3. 【Codeforces Round #433 (Div. 2) A】Fraction

    [链接]h在这里写链接 [题意] 在这里写题意 [题解] 枚举分子从高到低就好. 这样得到的一定是最大的. (可以约分没错,但是约分过后和就不是n了,所以不会有错的) [错的次数] 0 [反思] 在这 ...

  4. 【Codeforces Round #433 (Div. 1) C】Boredom(二维线段树)

    [链接]我是链接 [题意] 接上一篇文章 [题解] 接(点我进入)上一篇文章. 这里讲一种用类似二维线段树的方法求矩形区域内点的个数的方法. 我们可以把n个正方形用n棵线段树来维护. 第i棵线段树维护 ...

  5. 【Codeforces Round #433 (Div. 1) C】Boredom(树状数组)

    [链接]h在这里写链接 [题意] 给你一个n*n的矩阵. 其中每一列都有一个点. 任意两个点构成了矩形的两个对角点 ->即任意两个点确定了一个矩形. ->总共能确定n*(n-1)/2个矩形 ...

  6. 【Codeforces Round #424 (Div. 2) C】Jury Marks

    [Link]:http://codeforces.com/contest/831/problem/C [Description] 有一个人参加一个比赛; 他一开始有一个初始分数x; 有k个评委要依次对 ...

  7. 【Codeforces Round #432 (Div. 1) B】Arpa and a list of numbers

    [链接]h在这里写链接 [题意] 定义bad list是一个非空的.最大公约数为1的序列.给定一个序列,有两种操作:花费x将一个元素删除.花费y将一个元素加1,问你将这个序列变为good list所需 ...

  8. 【Codeforces Round #420 (Div. 2) C】Okabe and Boxes

    [题目链接]:http://codeforces.com/contest/821/problem/C [题意] 给你2*n个操作; 包括把1..n中的某一个数压入栈顶,以及把栈顶元素弹出; 保证压入和 ...

  9. 【Codeforces Round #420 (Div. 2) B】Okabe and Banana Trees

    [题目链接]:http://codeforces.com/contest/821/problem/B [题意] 当(x,y)这个坐标中,x和y都为整数的时候; 这个坐标上会有x+y根香蕉; 然后给你一 ...

随机推荐

  1. 改动UINavigationBar (导航栏)上NavigationBarItem 的字体大小和颜色的用法

    //创建一个左边button UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithTitle:@"<" ...

  2. OpenCASCADE中散乱Edge生成Wire

    OpenCASCADE中散乱Edge生成Wire eryar@163.com Abstract. In OpenCASCADE a wire can be built from any number ...

  3. AVEVA PDMS to 3ds Max - RvmTranslator6.0beta

    AVEVA PDMS to 3ds Max - RvmTranslator6.0beta eryar@163.com RvmTranslato6.0 translate PDMS RVM to 3ds ...

  4. POJ 2374 线段树建图+Dijkstra

    题意: 思路: 线段树+Dijkstra(要堆优化的) 线段树要支持打标记 一个栅栏 拆成两个点 :左和右 新加一个栅栏的时候 看看左端点有没有被覆盖过 如果有的话 就分别从覆盖的那条线段的左右向当前 ...

  5. Fedora Core 11 Alpha试用视频(由于youtube问题暂时无法访问)

    1.系统安装: http://www.youtube.com/watch?v=QcDy5eRQZ20   2.重启后配置   3.体验Fedora 11 Gnome2.25和Kde 4.2 http: ...

  6. 常用的130个vim命令

    最近VIM用的也越来越多了...因为确实在慢慢的把win下的编辑习惯转成unix下的编辑习惯..._vimrc也在不断的完善中先贴一下平时在VIM中使用中的命令...有很多也是我没有掌握的 (估计也是 ...

  7. java高质量缩放图片

    可按照比例缩放,也可以指定宽高 import com.sun.image.codec.jpeg.JPEGImageEncoder; import com.sun.image.codec.jpeg.JP ...

  8. 今日题解------codeforce 893d

    题意:给你一个数列,小于零表示表示信用卡里取出钱,大于零表示信用卡里存钱,等于零表示要查询信用卡, 如果被查到信用卡里的钱小于零,那你就GG,或者在任何时候你的信用卡里的钱大于d的话(不需要找ai等于 ...

  9. 【Hello 2018 C】Party Lemonade

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 处理出凑够2^j最少需要花费多少钱. 即试着把第i种物品买2^(j-i)个,看看会不会更便宜 记录在huafei[0..31]中 然 ...

  10. Git管理软件

    软件下载地址 首先下载库 https://code.google.com/p/msysgit/ 接着安装 https://code.google.com/p/tortoisegit/ 然后就能够用了