Alice's mooncake shop HDU - 4122
光是题目读懂都花了很多时间
题意: 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 }