原题链接

光是题目读懂都花了很多时间 

题意: n个订单,m长的营业时间(注意不止24h),给你月饼保鲜时长t,以及月饼制造成本s,求制作完N个订单的最小成本

这道题的小时制作成本是在1~m之间,也就是不是24小时制,我个人认为很坑的是第i小时的制作成本不是i~i+1小时,而是i-1~i小时.所以这道题如果订单时间为T,保鲜时长为t,我们要在T+1小时前制作完成(即在T+1行前可以制作月饼),保险时长是t,所能制作月饼的区间是[T-t,T],求此区间的最小值

此题可以证明直接在一个小时内做完比多个小时做完成本更低

这道题可以离线处理也可以一个个处理,如果离线处理,我们不知道月饼数目,难以计算总成本,因此可以计算单个成本

因为这道题不停WA,所以全用了long long(蒟蒻本质),实际出错点在,订单时间可以重复

 1 #include <iostream>
 2 #include <unordered_map>
 3 #include <cstdio> 
 4 using namespace std;
 5 #define ll long long
 6 const ll N = 100010;
 7 unordered_map<string,int> um;
 8 ll n,m,mon[15] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
 9 ll cost[N],q[N];
10 struct order{
11     ll T,cost,nums;
12 }order[2520];
13 ll Gettime(ll year,string month,ll day)
14 {//先计算到2000年有几个闰年 
15     ll sum = 0;
16     ll cnt = 0;
17     for(ll i=2000;i<year;i++)
18         if((i%4==0&&i%100!=0)||(i%400==0)) cnt++;
19     sum = (ll)max(year-2000-cnt,0ll)*365+366*cnt;
20     sum = sum*24ll;
21     ll monh = um[month];
22     if((year%4==0&&year%100!=0)||(year%400==0)) mon[2] = 29;
23     for(ll i=1;i<monh;i++) sum+=mon[i]*24ll;
24     for(ll i=1;i<day;i++) sum+=24ll;
25     return sum+1;
26 }
27 int main()
28 {
29     //freopen("in.txt","r",stdin);
30     um["Jan"] = 1; um["Feb"] = 2; um["Mar"] = 3; um["Apr"] = 4;
31     um["May"] = 5; um["Jun"] = 6; um["Jul"] = 7; um["Aug"] = 8;
32     um["Sep"] = 9; um["Oct"] = 10; um["Nov"] = 11; um["Dec"] = 12;
33     while(scanf("%lld%lld",&n,&m)!=EOF&&n&&m){
34         ll ans = 0;//所以订单一并处理,每个订单的时间是 [T-t,T] 我们直接求[1,m]的队列
35         ll tt = -1,hh = 0,s,t,id = 1; //t是存储时间 s是成本 
36         for(ll i=1;i<=n;i++){
37             mon[2] = 28;
38             ll day,year,hour,nums; char month[10];
39             scanf("%s%lld%lld%lld%lld",month,&day,&year,&hour,&order[i].nums);
40             string mont = month;
41             order[i].T = Gettime(year,mont,day)+hour;
42         } 
43         scanf("%lld%lld",&t,&s);
44         for(ll i=1;i<=m;i++){//单调队列需要维护队列的成本最小值 
45             ll expense;
46             scanf("%lld",&expense);//因为是离线处理,比较做一个月饼的成本 
47             while(hh<=tt&&cost[q[tt]]+(i-q[tt])*s>=expense) --tt;
48             q[++tt] = i;
49             cost[i] = expense;
50             while(id<=n&&i==order[id].T){
51                 while(hh<=tt&&q[hh]<order[id].T-(ll)t) ++hh;
52                 order[id].cost = order[id].nums*cost[q[hh]]+(ll)(i-q[hh])*s*order[id].nums;
53                 ans += order[id].cost; 
54                 id++;
55             }
56         }
57         printf("%lld\n",ans);
58     }
59     return 0;
60 }