http://acm.hdu.edu.cn/showproblem.php?pid=4122
题意:有n个订单,每个订单会告诉你那天那个时候会要多少个月饼,你要给他,订单按时间顺序给。
题目会告诉你一个月饼只能多保存t小时,每多保存一小时要s的价值。
以及前m小时的生产信息 ai (1<=i<=m) 表示 第i小时生产一个月饼要的价值。
要你输出完成所有的订单的最小价值,订单的时间不会超过m的时间 。
第一小时 默认是 2000.1.1——0点
第二小时 默认是 2000.1.1——1点
。。。。。。
案例: 取的是第9单位小时(即2000.1.1——8点)生产10个月饼 到订单的时间是1天,所以ans=((1 保存天数)*(2 s)+(ai 5))*10=70
显然针对每一个订单,有一个最优的取值,而这最优的取值必然是只取一小时的,然后全部生产完这个订单所需求的分量。
而对于不同时间的订单,前面时间的订单的 最优取的小时时间 <= 后面时间的订单的 最优取的小时时间
然后 单调队列,维护一个是否过期(保存时间超过t)。。。 通过判定 两个时间的 优劣性 加入 队尾。
1 #include<cstdio> 2 #include<iostream> 3 #include<vector> 4 using namespace std; 5 #include<algorithm> 6 #include<string> 7 #define N 2510 8 #define M 100010 9 #define inf 200000000 10 struct cust{ 11 int l,time; 12 }cus[N],qu[M]; 13 int mo(string str){ 14 if(str=="Jan") return 1; 15 if(str=="Feb") return 2; 16 if(str=="Mar") return 3; 17 if(str=="Apr") return 4; 18 if(str=="May") return 5; 19 if(str=="Jun") return 6; 20 if(str=="Jul") return 7; 21 if(str=="Aug") return 8; 22 if(str=="Sep") return 9; 23 if(str=="Oct") return 10; 24 if(str=="Nov") return 11; 25 if(str=="Dec") return 12; 26 } 27 int mon[12]={31,28,31,30,31,30,31,31,30,31,30,31}; 28 int okyear(int year){ 29 return year%400==0||year%100&&year%4==0; 30 } 31 int how(int year,int month,int date,int hour){ 32 int ans=0; 33 for(int i=2000;i<year;++i){ 34 if(okyear(i)) ans+=366; 35 else ans+=365; 36 } 37 for(int i=0;i<month-1;++i){ 38 if(okyear(year)&&i==1) ans+=29; 39 else ans+=mon[i]; 40 } 41 ans+=date-1; 42 ans=ans*24+hour; 43 return ans; 44 } 45 int main(){ 46 int n,m,a,b,c,s,t; 47 char str[5]; 48 while(scanf("%d%d",&n,&m)){ 49 if(!n&&!m) break; 50 for(int i=0;i<n;++i){ 51 scanf("%s%d%d%d%d",str,&a,&b,&c,&cus[i].l); 52 cus[i].time=how(b,mo(str),a,c); //时间什么的都转化成基本单位 小时 53 } 54 scanf("%d%d",&t,&s); 55 __int64 ans=0; 56 int start,top,tail; 57 top=tail=start=0; 58 for(int i=0;i<m;++i){ 59 scanf("%d",&a); 60 while(top<tail&&qu[tail-1].l+(i-qu[tail-1].time)*s>=a) tail--; //前面的时间比这个时间差就t了 61 qu[tail].l=a,qu[tail++].time=i; 62 while(start<n&&cus[start].time==i){ 63 while(top<tail-1&&qu[top].time+t<cus[start].time) top++; //过期的不要 64 ans+=(qu[top].l+(cus[start].time-qu[top].time)*s)*cus[start].l; 65 start++; 66 } 67 } 68 printf("%I64d\n",ans); 69 } 70 return 0; 71 }