hdu4122

题目很长,有点恶心,但实际上是个单调队列

没搞出来,题解 https://blog.csdn.net/lvshubao1314/article/details/46910271

#include<bits/stdc++.h>
#define ll long long 
using namespace std;

ll times[3000],num[100005],cost[100005],q[100005];//订单时间,订单数量,每个时间做蛋糕的代价,单调队列
ll n,m,T,S;//n个订单,m个做蛋糕时间(连续的),蛋糕寿命,每小时保存代价 
map<string,int>mp;
int sum[20];

void init(){
    mp["Jan"]=1,mp["Feb"]=2,mp["Mar"]=3;
    mp["Apr"]=4,mp["Mar"]=5,mp["Jun"]=6;
    mp["Jul"]=7,mp["Aug"]=8,mp["Sep"]=9;
    mp["Oct"]=10,mp["Nov"]=11,mp["Dec"]=12;
    sum[0]=0,sum[1]=31,sum[2]=sum[1]+28,sum[3]=sum[2]+31,sum[4]=sum[3]+30,sum[5]=sum[4]+31,sum[6]=sum[5]+30;
    sum[7]=sum[6]+31,sum[8]=sum[7]+31,sum[9]=sum[8]+30,sum[10]=sum[9]+31,sum[11]=sum[10]+30;
}
int get(int y,int m,int d,int t)
{
    int ans=0;
    for(int i=2000; i<y; i++)
    {
        if((i%4==0&&i%100!=0)||i%400==0)
            ans+=366;
        else
            ans+=365;
    }
    if((y%4==0&&y%100!=0)||y%400==0)
    {
        ans+=sum[m-1];
        if(m-1>=2)ans++;
    }
    else
    {
        ans+=sum[m-1];
    }
    ans+=(d-1);
    return ans*24+t;
}

int main(){
    init();
    while(scanf("%lld%lld",&n,&m),n){
        for(int i=0;i<n;i++){
            int year,day,t;
            char mon[10];
            scanf("%s%d%d%d%lld",mon,&day,&year,&t,&num[i]);
            times[i]=get(year,mp[mon],day,t);
        }
        scanf("%lld%lld",&T,&S);
        int tail=0,head=0,k=0;
        ll cnt=0;
        for(int i=0;i<m;i++){
            scanf("%lld",&cost[i]);
            while(head<tail && cost[q[tail-1]]+S*(i-q[tail-1])>=cost[i])tail--;//单调队列不是按照cost排序,而是按照制作成本+保存成本从小到大排序 
            q[tail++]=i;
            while(i==times[k]){
                while(head<tail-1 && i-q[head]>T) head++;
                cnt+=num[k]*(cost[q[head]]+S*(i-q[head]));
                k++;
            }
        }
        printf("%lld\n",cnt);
    }
}

 

posted on 2018-12-29 18:07  zsben  阅读(152)  评论(0编辑  收藏  举报

导航