1. 程式人生 > 實用技巧 >Alice's mooncake shop HDU - 4122

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 }