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 }

转载于:https://www.cnblogs.com/slon/archive/2012/02/21/2361864.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值