hdu 4122 Alice's mooncake shop(单调队列)

题目链接:hdu 4122 Alice‘s mooncake shop

题目大意:给定N和M,表示有N个订单,M个时刻可以做月饼,时刻以小时计算,任意时刻可以做若干个月饼。接着

N行为N个订单的信息,包括时间和数量。再给定T和S,表示每个月饼的保质时间和每保存一小时的开销。然后M行为

对应每个时刻制作月饼的代价。问说最少花费多少代价完成所有订单。

解题思路:单调队列或者RMQ,单调队列即用一个deque维护一个代价递增的队列,每次将头部保质期不够的剔除。

RMQ可以将预处理处每个区间时刻代价的最小值,需要加上保存的代价,然后对于每个订单只要查询单前位置向前T

小时以内的最小值即可。

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>

using namespace std;
const char month[15][10] = {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov"};
const int day[15] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
typedef pair<int,int> pii;
typedef long long ll;

int N, M;
deque<pii> Q;
queue<pii> G;

inline int get_month(char* s) {
    for (int i = 1; i <= 11; i++)
        if (strcmp(s, month[i]) == 0)
            return i;
    return 12;
}

inline bool Leap_year(int x) {
    return (x % 4 == 0 && x % 100) || x % 400 == 0;
}

int get_time() {
    char mon[10];
    int y, d, h, m;
    scanf("%s%d%d%d", mon, &d, &y, &h);
    m = get_month(mon);

    int ret = 0;
    for (int i = 2000; i < y; i++)
        ret += Leap_year(i) ? 366 : 365;

    for (int i = 1; i < m; i++) {
        if (i == 2 && Leap_year(y))
            ret += 29;
        else
            ret += day[i];
    }
    ret += d - 1;
    return ret * 24 + h;
}

void init () {
    int ti, x;
    Q.clear();

    for (int i = 0; i < N; i++) {
        ti = get_time();
        scanf("%d", &x);
        G.push(make_pair(x, ti));
    }
}

ll solve () {
    int S, T, x;
    ll ret = 0;
    scanf("%d%d", &T, &S);
    for (int i = 0; i < M; i++) {
        scanf("%d", &x);
        while (!Q.empty() && x <= Q.back().first + (i - Q.back().second) * S)
            Q.pop_back();
        Q.push_back(make_pair(x, i));
        while (!G.empty() && i == G.front().second) {
            while (!Q.empty() && Q.front().second + T < i)
                Q.pop_front();
            ret += (Q.front().first + (i - Q.front().second) * S) * G.front().first;
            G.pop();
        }
    }
    return ret;
}

int main () {
    while (scanf("%d%d", &N, &M) == 2 && N + M) {
        init();
        printf("%I64d\n", solve());
    }
    return 0;
}

hdu 4122 Alice's mooncake shop(单调队列)

时间: 2024-08-08 18:59:08

hdu 4122 Alice's mooncake shop(单调队列)的相关文章

HDU 4122 Alice&#39;s mooncake shop 单调队列优化dp

Alice's mooncake shop Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4122 Description The Mid-Autumn Festival, also known as the Moon Festival or Zhongqiu Festival is a popular harvest festival celebrated by Ch

【单调队列】HDU 4122 Alice&#39;s mooncake shop

通道:http://acm.hdu.edu.cn/showproblem.php?pid=4122 题意:给定N和M,表示有N个订单,M个时刻可以做月饼,时刻以小时计算,任意时刻可以做若干个月饼.接着N行为N个订单的信息,包括时间和数量.再给定T和S,表示每个月饼的保质时间和每保存一小时的开销.然后M行为对应每个时刻制作月饼的代价.问说最少花费多少代价完成所有订单 思路:维护单调队列,把之前的花费大于当前的pop掉,把不满足保鲜期内的pop掉 代码:https://github.com/Mith

hdu 4122 Alice&#39;s mooncake shop

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4122 题意大意是Alice开着一家月饼店,可以接到n做月饼的订单,而Alice只有在从2000年一月一日0点为第一个小时开始的前m个小时内做月饼,而且只能在整点 的时候做月饼,并且做月饼不花费时间,也就是一瞬间就可以做超级多的月饼,而每个月饼有t个小时的保质期,每个月饼保存每小时需要花费s元,而在可以 做月饼的m小时内,不同小时做月饼花费的钱也不同,每个订单都有交付订单嗯达时间,某年某月某日某时交付该

hdu4122 Alice&#39;s mooncake shop 单调队列

http://acm.hdu.edu.cn/showproblem.php?pid=4122 Alice's mooncake shop Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2908    Accepted Submission(s): 744 Problem Description The Mid-Autumn Festi

HDU 4122 Alice&#39;s mooncake shop --RMQ

题意: 一个月饼店做月饼,总营业时间m小时,只能在整点做月饼,可以做无限个,不过在不同的时间做月饼的话每个月饼的花费是不一样的,假设即为cost[i],再给n个订单,即为在某个时间要多少个月饼,时间从2000年1月1日0时开始计算,必须在每个订单的时间之前完成这么多月饼,月饼还有保质期T小时以及保存费用S每小时,现在问满足这n个点的最小成本是多少. 解法: 因为月饼有保质期T,所以第i个月饼只能在[Ti-T+1,Ti]时间内做好.如果时间j有订单,假设在时间i做月饼是最好的,那么这个订单每个月饼

hdu 4122 Alice&#39;s mooncake shop (线段树)

题目大意: 一个月饼店每个小时做出月饼的花费不一样. 储存起来要钱,最多存多久.问你把所有订单做完的最少花费. 思路分析: ans = segma( num[]*(cost[] + (i-j)*s) ) 整理一下会发现式子就是 cost[]-j*s + i*s 对于每一个订单,我们把i拿出来分析 所以也就用cost - j*s 建树. 然后在储存期间找到最小的花费就行了. #include <cstdio> #include <iostream> #include <algo

【HDOJ】4122 Alice&#39;s mooncake shop

RMQ的基础题目,简单题. 1 /* 4122 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque>

hdu 4122 Alice&amp;#39;s mooncake shop (线段树)

题目大意: 一个月饼店每一个小时做出月饼的花费不一样. 储存起来要钱.最多存多久.问你把全部订单做完的最少花费. 思路分析: ans = segma( num[]*(cost[] + (i-j)*s) ) 整理一下会发现式子就是 cost[]-j*s + i*s 对于每个订单,我们把i拿出来分析 所以也就用cost - j*s 建树. 然后在储存期间找到最小的花费即可了. #include <cstdio> #include <iostream> #include <algo

HDU 3415 Max Sum of Max-K-sub-sequence 单调队列题解

本题又是一题单调队列题解. 技巧就是需要计算好前n项和Sn = a1 + a2 + ... an 这样方便处理. 记录一条单调队列,其意义是: q(head), q(head+1), ...q(tail) 其中头q(head)代表当前最佳解的起点 这样我们只需要在求某点为结尾的S[i] - S[q(head)就得到当前最佳值. 了解了单调数列,知道其中的记录意义,那么这道题就没有难度了.我也是了解这些信息之后就自己敲出代码的. 不过有些细节没写好也让我WA了几次. 最近少刷水题,而一直都是每天一