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

来源:http://acm.hdu.edu.cn/showproblem.php?pid=4122

题意:有n个订单,每个订单会告诉你那天那个时候会要多少个月饼,你要给他,订单按时间顺序给。题目会告诉你一个月饼只能多保存t小时,每多保存一小时要s的价值。以及前m小时的生产信息  ai (1<=i<=m) 表示 第i小时生产一个月饼要的价值。要你输出完成所有的订单的最小价值,订单的时间不会超过m的时间 。

 

#include<iostream>
#include<algorithm>
#include<iomanip>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#include<queue>
#include<map>
#include<set>
using namespace std;

struct node
{
    int l,time;
} data[2505],qu[100005];
int month(string str)
{
    if(str=="Jan") return 1;
    if(str=="Feb") return 2;
    if(str=="Mar") return 3;
    if(str=="Apr") return 4;
    if(str=="May") return 5;
    if(str=="Jun") return 6;
    if(str=="Jul") return 7;
    if(str=="Aug") return 8;
    if(str=="Sep") return 9;
    if(str=="Oct") return 10;
    if(str=="Nov") return 11;
    if(str=="Dec") return 12;
}
int monthn[12]= {31,28,31,30,31,30,31,31,30,31,30,31};
int okyear(int year)
{
    return year%400==0||year%100&&year%4==0;
}
int how(int year,int monthnth,int date,int hour)
{
    int ans=0;
    for(int i=2000; i<year; ++i)
    {
        if(okyear(i))
            ans+=366;
        else ans+=365;
    }
    for(int i=0; i<monthnth-1; ++i)
    {
        if(okyear(year)&&i==1)
            ans+=29;
        else ans+=monthn[i];
    }
    ans+=date-1;
    ans=ans*24+hour;
    return ans;
}
int main()
{
    int n,m,a,b,c,s,t;
    char str[5];
    while(scanf("%d%d",&n,&m))
    {
        if(!n&&!m) break;
        for(int i=0; i<n; ++i)
        {
            scanf("%s%d%d%d%d",str,&a,&b,&c,&data[i].l);
            data[i].time=how(b,month(str),a,c);
        }
        scanf("%d%d",&t,&s);
        __int64 ans=0;
        int start,top,tail;
        top=tail=start=0;
        for(int i=0; i<m; ++i)
        {
            scanf("%d",&a);
            while(top<tail&&qu[tail-1].l+(i-qu[tail-1].time)*s>=a)
                tail--;
            qu[tail].l=a,qu[tail++].time=i;
            while(start<n&&data[start].time==i)
            {
                while(top<tail-1&&qu[top].time+t<data[start].time)
                    top++;
                ans+=(qu[top].l+(data[start].time-qu[top].time)*s)*data[start].l;
                start++;
            }
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值