首页 > 代码库 > hdu 4122 Alice's mooncake shop (线段树)
hdu 4122 Alice's mooncake shop (线段树)
题目大意:
一个月饼店每个小时做出月饼的花费不一样。
储存起来要钱,最多存多久。问你把所有订单做完的最少花费。
思路分析:
ans = segma( num[]*(cost[] + (i-j)*s) )
整理一下会发现式子就是
cost[]-j*s + i*s
对于每一个订单,我们把i拿出来分析
所以也就用cost - j*s 建树。
然后在储存期间找到最小的花费就行了。
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <string> #define lson num<<1,s,mid #define rson num<<1|1,mid+1,e #define maxn 2555 #define maxm 100005 #define inf 0x3f3f3f3f using namespace std; typedef long long LL; int n,m; int days[2][13]={{0,31,28,31,30,31,30,31,31,30,31,30,31}, {0,31,29,31,30,31,30,31,31,30,31,30,31}}; string tab[] = {"","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; LL tre[maxm<<2]; int getmonth(string x) { for(int i=1;i<=12;i++) if(x==tab[i])return i; } bool leap(int x) { if(((x%4==0) && x%100!=0) || x%400==0)return true; return false; } LL gethour(int month,int day,int year,int hour) { LL res=day-1; int is=leap(year); for(int i=1;i<month;i++)res+=days[is][i]; for(int i=2000;i<year;i++) res+=365+leap(i); res*=24; res+=hour+1; return res; } void build(int num,int s,int e) { tre[num]=inf; if(s==e)return; int mid=(s+e)>>1; build(lson); build(rson); } void update(int num,int s,int e,int pos,LL val) { if(s==e) { tre[num]=val; return; } int mid=(s+e)>>1; if(pos<=mid)update(lson,pos,val); else update(rson,pos,val); tre[num]=min(tre[num<<1],tre[num<<1|1]); } LL query(int num,int s,int e,int l,int r) { if(l<=s && r>=e) { return tre[num]; } int mid=(s+e)>>1; if(r<=mid)return query(lson,l,r); else if(l>mid)return query(rson,l,r); else return min(query(lson,l,mid),query(rson,mid+1,r)); } string tmp; LL num[maxn]; LL cost[maxm]; LL time[maxm]; int main() { while(cin>>n>>m) { if(n==0 && m==0)break; for(int i=1;i<=n;i++) { int d,y,h,Num; cin>>tmp; cin>>d>>y>>h>>Num; num[i]=Num; time[i]=gethour(getmonth(tmp),d,y,h); } LL S,T; build(1,1,m); cin>>T>>S; for(int i=1;i<=m;i++) { cin>>cost[i]; cost[i]-=i*S; update(1,1,m,i,cost[i]); } LL ans=0; for(int i=1;i<=n;i++) { if(time[i]>m)break; ans+=num[i]*(query(1,1,m,max(1LL,time[i]-T+1),time[i])+time[i]*S); } cout<<ans<<endl; } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。