设在时间t有一个订单,要N个月饼,每个月饼每小时储存话费为S,设i时刻的制作单价为Vi,那么在i时刻(i>=t-T)去制作的花费为Vi*N+(T-i)*S*N
变形一下变成T*S*N+N*(Vi-i*S),这个等式中只有Vi-i*S和i的选取有关,所以实际上就是要找出在t[i]到t[i]-T范围内最大的Vi-i*S即可。用线段树实现。
算时间时一定要仔细写,把dec写成dev WA了 N次!
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 100005
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define INF 10000000
#define LL long long
LL V[maxn];
LL Min[maxn<<2];
LL Ord[maxn];
LL t[maxn];
int N,M,T,S;
void pushup(int rt){
Min[rt]=min(Min[rt<<1],Min[rt<<1|1]);
}
void build(int l,int r,int rt){
if(l==r){
Min[rt]=V[l];
return;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
LL query(int L,int R,int l,int r,int rt){
if(L<=l&&R>=r) return Min[rt];
int m=(l+r)>>1;
LL res=10000000;
if(m>=L) res=min(res,query(L,R,lson));
if(m<R) res=min(res,query(L,R,rson));
return res;
}
bool isleapyear(int n){
return n % 4 == 0 && n % 100 != 0 || n % 400 == 0;
}
LL Time(char *m, int d, int y, int h){
LL res=0;
for(int i=2000; i<y; i++){
if(isleapyear(i)) res += 366 * 24;
else res += 365 * 24;
}
if(strcmp(m,"Jan")==0) res+=0;
else if(strcmp(m,"Feb")==0) res+=31*24;
else if(strcmp(m,"Mar")==0) res+=59*24;
else if(strcmp(m,"Apr")==0) res+=90*24;
else if(strcmp(m,"May")==0) res+=120*24;
else if(strcmp(m,"Jun")==0) res+=151*24;
else if(strcmp(m,"Jul")==0) res+=181*24;
else if(strcmp(m,"Aug")==0) res+=212*24;
else if(strcmp(m,"Sep")==0) res+=243*24;
else if(strcmp(m,"Oct")==0) res+=273*24;
else if(strcmp(m,"Nov")==0) res+=304*24;
else if(strcmp(m,"Dec")==0) res+=334*24;
res+=(d-1)*24;
res+=h+1;
if((isleapyear(y))&&(strcmp(m,"Jan")!=0)&&(strcmp(m,"Feb")!=0)){
res+=24;
}
return res;
}
int main(){
while(~scanf("%d%d",&N,&M)){
if(!N&&!M) break;
for(int i=1;i<=N;i++){
char month[10];
int d,y,h,o;
scanf("%s%d%d%d%d",month,&d,&y,&h,&o);
t[i]=Time(month,d,y,h);
Ord[i]=o;
}
scanf("%d%d",&T,&S);
for(int i=1;i<=M;i++){
int tmp;
scanf("%d",&tmp);
V[i]=tmp-i*S;
}
build(1,M,1);
LL res=0;
for(int i=1;i<=N;i++){
LL s=(t[i]-T)>=1?(t[i]-T):1;
if((t[i]-T)>M) continue;
LL tmp=query(s,t[i],1,M,1);
res+=(tmp+t[i]*S)*Ord[i];
}
printf("%I64d\n",res);
}
return 0;
}