来源: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;
}