HDU 4122 Alice'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 Chinese people, dating back over 3,000 years to moon worship in China‘s Shang Dynasty. The Zhongqiu Festival is held on the 15th day of the eighth month in the Chinese calendar, which is in September or early October in the Gregorian calendar. It is a date that parallels the autumnal equinox of the solar calendar, when the moon is at its fullest and roundest.

The
traditional food of this festival is the mooncake. Chinese family
members and friends will gather to admire the bright mid-autumn harvest
moon, and eat mooncakes under the moon together. In Chinese, “round”(圆)
also means something like “faultless” or “reuion”, so the roundest moon,
and the round mooncakes make the Zhongqiu Festival a day of family
reunion.

Alice has opened up a 24-hour mooncake shop. She always
gets a lot of orders. Only when the time is K o’clock sharp( K = 0,1,2
…. 23) she can make mooncakes, and We assume that making cakes takes no
time. Due to the fluctuation of the price of the ingredients, the cost
of a mooncake varies from hour to hour. She can make mooncakes when the
order comes,or she can make mooncakes earlier than needed and store them
in a fridge. The cost to store a mooncake for an hour is S and the
storage life of a mooncake is T hours. She now asks you for help to work
out a plan to minimize the cost to fulfill the orders.

Input

The input contains no more than 10 test cases.
For each test case:

The first line includes two integers N and M. N is the total number of orders. M is the number of hours the shop opens.

The next N lines describe all the orders. Each line is in the following format:

month date year H R

It means that on a certain
date, a customer orders R mooncakes at H o’clock. “month” is in the
format of abbreviation, so it could be "Jan", "Feb", "Mar", "Apr",
"May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov" or "Dec". H and R are
all integers.

All the orders are sorted by the time in increasing order.

The next line contains T and S meaning that the storage life
of a mooncake is T hours and the cost to store a mooncake for an hour is
S.

Finally, M lines follow. Among those M lines, the i th line( i starts from 1) contains a integer indicating the cost to make a mooncake during the i th hour . The cost is no more than 10000. Jan 1st 2000 0 o‘clock belongs to the 1 st hour, Jan 1st 2000 1 o‘clock belongs to the 2 nd hour, …… and so on.

(0<N <= 2500; 0 < M,T <=100000; 0<=S <= 200; R<=10000 ; 0<=H<24)

The input ends with N = 0 and M = 0.

Output

You should output one line for each test case: the minimum cost.

Sample Input

1 10 Jan 1 2000 9 10 5 2 20 20 20 10 10 8 7 9 5 10 0 0

Sample Output

70 

HINT

题意

Alice开了家月饼店,现有2500笔订单,订单包括某小时(2000年1月1日0点算第1个小时的开始)和需要的月饼数量。然后给你前100000小时的信息,包括第i个小时做1个饼的花费cost[i]。然后给你月饼的保质期T(说明订单i只能买[order[i].hour-T ,order[i].hour ]这个区间生产的饼)和保存1小时的花费S,让你求最小的花费满足所有订单。

题解:

首先要把订单的时间转化成自2000年1月1日0点开始的第几小时,由于最多100000小时,所以最大到2012年的样子。然后维护一个最小值的单调队列。

具体实现:

首先我们已经获得第一个Order的单调队列,记为LQ,然后是处理第2个订单,我们把LQ分成2个部分。A:下标在order[2].hour-T, order[1].hour范围(A集合可能为空) B:下标在order[1].hour , order[2].hour的范围。对于A,由于第2个订单也可能使用到A集合里面的元素,所以我们要先对A集合所有元素加上1.2订单时间差的花费S*(order[2].hour- order[1].hour)(用于保存),然后再把B集合的元素加到单调队列里面,最后队列头的值即为第2个订单得到一个饼的最小花费,乘以订单数即可。之后的每个订单同样处理即可。注意,答案要long long

http://altynai.me/2011/11/hdu-4121-4123/

代码

#include<iostream>
#include<stdio.h>
#include<vector>
#include<deque>
#include<queue>
#include<cstring>
using namespace std;
int n,m;
long long ans = 0;
string mon[20]={"", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov","Dec"};
int day[20]={0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
string M;
int d,y,h,num;
long long time[2505];
deque<pair<int,int> > QQ;
queue<pair<int,int> > Q;
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        int tot = 0;
        if(n==0&&m==0)break;
        while(!QQ.empty())QQ.pop_back();
        while(!Q.empty())Q.pop();
        memset(time,0,sizeof(time));
        for(int i=0;i<n;i++)
        {
            cin>>M;
            scanf("%d%d%d%d",&d,&y,&h,&num);
            for(int j=2000;j<y;j++)
            {
                if(( j % 4 == 0 && j % 100) || j % 400 == 0 )d += 366;
                else d += 365;
            }
            int k;
            for(k=1;k<=12;k++)
                if(mon[k]==M)
                    break;
            for(int j=1;j<k;j++)
            {
                if(j==2 &&( ( y % 4 == 0 && y % 100) || y % 400 == 0 ))
                    d += 29;
                else
                    d += day[j];
            }
            d--;
            Q.push(make_pair(num,d*24+h));
        }

        int T,S;
        scanf("%d%d",&T,&S);
        long long ans = 0;
        for(int i=0;i<m;i++)
        {
            int x;
            scanf("%d",&x);
            while(!QQ.empty()&&x<=QQ.back().first + (i-QQ.back().second)*S)
                QQ.pop_back();
            QQ.push_back(make_pair(x,i));
            while(!Q.empty()&&i==Q.front().second)
            {
                while(!QQ.empty() && QQ.front().second + T < i )
                    QQ.pop_front();
                ans += (QQ.front().first + (i - QQ.front().second) * S) * Q.front().first;
                Q.pop();
            }
        }
        printf("%lld\n",ans);
    }
}

HDU 4122 Alice's mooncake shop 单调队列优化dp

时间: 2024-12-20 17:13:39

HDU 4122 Alice's mooncake shop 单调队列优化dp的相关文章

hdu 4122 Alice&#39;s mooncake shop(单调队列)

题目链接:hdu 4122 Alice's mooncake shop 题目大意:给定N和M,表示有N个订单,M个时刻可以做月饼,时刻以小时计算,任意时刻可以做若干个月饼.接着 N行为N个订单的信息,包括时间和数量.再给定T和S,表示每个月饼的保质时间和每保存一小时的开销.然后M行为 对应每个时刻制作月饼的代价.问说最少花费多少代价完成所有订单. 解题思路:单调队列或者RMQ,单调队列即用一个deque维护一个代价递增的队列,每次将头部保质期不够的剔除. RMQ可以将预处理处每个区间时刻代价的最

【单调队列】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

HDU 4374 One hundred layer(单调队列优化dp)

题意:有一个n*m的矩阵,每格有一个分数,一个人站在(1,x)位置,在每一行中,他只能朝一个方向走(向左或向右),且最多走t步,问走到最后第n行得到的最大分数. 思路:不难想到状态转移方程dp[i][j] = max(dp[i-1][k]+sum[i][j]-sum[i][k-1]),(k<j) 移项得 dp[i][j]-sum[i][j] = max(dp[i-1][k] - sum[i][k-1]); 方程右侧与i,j无关,所以可以用单调队列维护max(dp[i-1][k] - sum[i]

hdu 3415 Max Sum of Max-K-sub-sequence 单调队列优化DP

题目链接: https://www.cnblogs.com/Draymonder/p/9536681.html 同上一篇文章,只是 需要记录最大值的开始和结束的位置 #include <iostream> #include <string.h> #include <cmath> using namespace std; const int N = 1e5 + 10; int n,k; int s[N<<1],sum[N<<1]; int Q[N&

【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>