题目很长,有点恶心,但实际上是个单调队列
没搞出来,题解 https://blog.csdn.net/lvshubao1314/article/details/46910271
#include#define ll long long using namespace std; ll times[3000],num[100005],cost[100005],q[100005];//订单时间,订单数量,每个时间做蛋糕的代价,单调队列 ll n,m,T,S;//n个订单,m个做蛋糕时间(连续的),蛋糕寿命,每小时保存代价 map<string,int>mp; int sum[20]; void init(){ mp["Jan"]=1,mp["Feb"]=2,mp["Mar"]=3; mp["Apr"]=4,mp["Mar"]=5,mp["Jun"]=6; mp["Jul"]=7,mp["Aug"]=8,mp["Sep"]=9; mp["Oct"]=10,mp["Nov"]=11,mp["Dec"]=12; sum[0]=0,sum[1]=31,sum[2]=sum[1]+28,sum[3]=sum[2]+31,sum[4]=sum[3]+30,sum[5]=sum[4]+31,sum[6]=sum[5]+30; sum[7]=sum[6]+31,sum[8]=sum[7]+31,sum[9]=sum[8]+30,sum[10]=sum[9]+31,sum[11]=sum[10]+30; } int get(int y,int m,int d,int t) { int ans=0; for(int i=2000; i ) { if((i%4==0&&i%100!=0)||i%400==0) ans+=366; else ans+=365; } if((y%4==0&&y%100!=0)||y%400==0) { ans+=sum[m-1]; if(m-1>=2)ans++; } else { ans+=sum[m-1]; } ans+=(d-1); return ans*24+t; } int main(){ init(); while(scanf("%lld%lld",&n,&m),n){ for(int i=0;i ){ int year,day,t; char mon[10]; scanf("%s%d%d%d%lld",mon,&day,&year,&t,&num[i]); times[i]=get(year,mp[mon],day,t); } scanf("%lld%lld",&T,&S); int tail=0,head=0,k=0; ll cnt=0; for(int i=0;i ){ scanf("%lld",&cost[i]); while(head 1]]+S*(i-q[tail-1])>=cost[i])tail--;//单调队列不是按照cost排序,而是按照制作成本+保存成本从小到大排序 q[tail++]=i; while(i==times[k]){ while(head 1 && i-q[head]>T) head++; cnt+=num[k]*(cost[q[head]]+S*(i-q[head])); k++; } } printf("%lld\n",cnt); } }