标签:
Time Limit: 20 Sec
Memory Limit: 256 MB
http://acm.hdu.edu.cn/showproblem.php?pid=4122
Input
Output
You should output one line for each test case: the minimum cost.
Sample Input
Sample Output
70
题意
Alice开了家月饼店,现有2500笔订单,订单包括某小时(2000年1月1日0点算第1个小时的开始)和需要的月饼数量。然后给你前100000小时的信息,包括第i个小时做1个饼的花费cost[i]。然后给你月饼的保质期T(说明订单i只能买[order[i].hour-T ,order[i].hour ]
这个区间生产的饼)和保存1小时的花费S,让你求最小的花费满足所有订单。
题解:
首先要把订单的时间转化成自2000年1月1日0点开始的第几小时,由于最多100000小时,所以最大到2012年的样子。然后维护一个最小值的单调队列。
具体实现:
首先我们已经获得第一个Order的单调队列,记为LQ,然后是处理第2个订单,我们把LQ分成2个部分。A:下标在order[2].hour-T, order[1].hour
范围(A集合可能为空) B:下标在order[1].hour , order[2].hour
的范围。对于A,由于第2个订单也可能使用到A集合里面的元素,所以我们要先对A集合所有元素加上1.2订单时间差的花费S*(order[2].hour- order[1].hour)
(用于保存),然后再把B集合的元素加到单调队列里面,最后队列头的值即为第2个订单得到一个饼的最小花费,乘以订单数即可。之后的每个订单同样处理即可。注意,答案要long long
。
http://altynai.me/2011/11/hdu-4121-4123/
代码
#include<iostream> #include<stdio.h> #include<vector> #include<deque> #include<queue> #include<cstring> using namespace std; int n,m; long long ans = 0; string mon[20]={"", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov","Dec"}; int day[20]={0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; string M; int d,y,h,num; long long time[2505]; deque<pair<int,int> > QQ; queue<pair<int,int> > Q; int main() { while(scanf("%d%d",&n,&m)!=EOF) { int tot = 0; if(n==0&&m==0)break; while(!QQ.empty())QQ.pop_back(); while(!Q.empty())Q.pop(); memset(time,0,sizeof(time)); for(int i=0;i<n;i++) { cin>>M; scanf("%d%d%d%d",&d,&y,&h,&num); for(int j=2000;j<y;j++) { if(( j % 4 == 0 && j % 100) || j % 400 == 0 )d += 366; else d += 365; } int k; for(k=1;k<=12;k++) if(mon[k]==M) break; for(int j=1;j<k;j++) { if(j==2 &&( ( y % 4 == 0 && y % 100) || y % 400 == 0 )) d += 29; else d += day[j]; } d--; Q.push(make_pair(num,d*24+h)); } int T,S; scanf("%d%d",&T,&S); long long ans = 0; for(int i=0;i<m;i++) { int x; scanf("%d",&x); while(!QQ.empty()&&x<=QQ.back().first + (i-QQ.back().second)*S) QQ.pop_back(); QQ.push_back(make_pair(x,i)); while(!Q.empty()&&i==Q.front().second) { while(!QQ.empty() && QQ.front().second + T < i ) QQ.pop_front(); ans += (QQ.front().first + (i - QQ.front().second) * S) * Q.front().first; Q.pop(); } } printf("%lld\n",ans); } }
HDU 4122 Alice's mooncake shop 单调队列优化dp
标签:
原文地址:http://www.cnblogs.com/qscqesze/p/4918773.html