首页 > 代码库 > HDU 4122 Alice's mooncake shop --RMQ
HDU 4122 Alice's mooncake shop --RMQ
题意: 一个月饼店做月饼,总营业时间m小时,只能在整点做月饼,可以做无限个,不过在不同的时间做月饼的话每个月饼的花费是不一样的,假设即为cost[i],再给n个订单,即为在某个时间要多少个月饼,时间从2000年1月1日0时开始计算,必须在每个订单的时间之前完成这么多月饼,月饼还有保质期T小时以及保存费用S每小时,现在问满足这n个点的最小成本是多少。
解法:
因为月饼有保质期T,所以第i个月饼只能在[Ti-T+1,Ti]时间内做好。
如果时间j有订单,假设在时间i做月饼是最好的,那么这个订单每个月饼的
花费为 cost[i] + (j-i)*S = cost[i]-i*S + j*S, 由于j不变,所以求cost[i]-i*S的
最小值即可,即求[Ti-T+1,Ti]内的cost[i]-i*S最小值,求区间最小值我们用RMQ可以快速求出
这里RMQ用了一个Log函数优化,使得到k的时间复杂度为O(1)
这里的月份处理采用了kuangbin大神的模板,简洁又好用。
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <algorithm>#define lll __int64using namespace std;#define N 100017lll d[N][21],cost[N];int LOG[N],n;int getmonth(char s[]){ if(strcmp(s,"Jan") == 0) return 1; if(strcmp(s,"Feb") == 0) return 2; if(strcmp(s,"Mar") == 0) return 3; if(strcmp(s,"Apr") == 0) return 4; if(strcmp(s,"May") == 0) return 5; if(strcmp(s,"Jun") == 0) return 6; if(strcmp(s,"Jul") == 0) return 7; if(strcmp(s,"Aug") == 0) return 8; if(strcmp(s,"Sep") == 0) return 9; if(strcmp(s,"Oct") == 0) return 10; if(strcmp(s,"Nov") == 0) return 11; if(strcmp(s,"Dec") == 0) return 12;}int days[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};bool isleap(int y){ if(y % 400 == 0 || (y % 100 != 0 && y%4 == 0))return true; else return false;}struct Node{ char mon[10]; int d,y,h,R; lll tim; void input() { scanf("%s%d%d%d%d",mon,&d,&y,&h,&R); tim = 0; for(int i = 2000;i < y;i++) { if(isleap(i)) tim += 366*24; else tim += 365*24; } for(int i = 1;i < getmonth(mon);i++) tim += days[i]*24; if(isleap(y) && getmonth(mon) > 2) tim += 24; tim += (d-1)*24; tim += h+1; }}order[2704];void RMQ_init(int m){ int i,j; for(i=1;i<=m;i++) d[i][0] = cost[i]; for(j=1;(1<<j)<=m;j++) { for(i=1;i+(1<<j)-1<=m;i++) d[i][j] = min(d[i][j-1],d[i+(1<<(j-1))][j-1]); }}void getLog(int n){ for(int i=0;i<=n;i++) LOG[i] = (int)(log((double)i)/log(2.0));}lll RMQ(int l,int r){ int k = LOG[r-l+1]; return min(d[l][k],d[r-(1<<k)+1][k]);}int main(){ int n,m,T,S,i,j; while(scanf("%d%d",&n,&m)!=EOF && n+m) { getLog(m); for(i=1;i<=n;i++) order[i].input(); scanf("%d%d",&T,&S); for(i=1;i<=m;i++) { scanf("%I64d",&cost[i]); cost[i] -= i*S; } RMQ_init(m); lll ans = 0; for(i=1;i<=n;i++) { if(order[i].tim < 0 || order[i].tim > m) continue; int L = max(1LL,order[i].tim - T + 1); int R = order[i].tim; lll MN = RMQ(L,R); ans += (MN+order[i].tim*S)*order[i].R; } cout<<ans<<endl; } return 0;}
HDU 4122 Alice's mooncake shop --RMQ
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。