hdu 4122 (poj 4002) Alice's mooncake shop 2011福州赛

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)。。。   通过判定 两个时间的 优劣性 加入 队尾。

 

View Code
 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 }

你可能感兴趣的:(poj)