单调队列——HDU4122

注意不是优先队列,因为优先队列只能对队头进行操作,所以……单调队列,从队头到队尾所有都可以操作

 

http://acm.hdu.edu.cn/showproblem.php?pid=4122

一开始把时间,什么年月日,转化为时间小时(开始搞错WA了一次)

后来使用单调队列,维护队列,使之到i 生产的最优,过期的出队列

单调队列——HDU4122 View Code
#include<stdio.h>

#include<string.h>

#include<iostream>

#include<algorithm>

using namespace std;



char Month[13][9]={"","Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov" , "Dec"};

__int64 days[12]={31,28,31,30,31,30,31,31,30,31,30,31};





inline __int64 leap(__int64 year)

{

    return ((year%4==0&&year%100!=0)||year%400==0);

}



struct DD

{

    __int64 year,month,day,hour;

};



__int64 data__int64(DD a)

{

    __int64 ret=0;//(a.year-2000)*365+(a.year-2000)/4-(a.year-2000)/100+(a.year-2000)/400;

    int i;

    for(i=2000;i<a.year;i++)

        ret+=365+leap(i);

    days[1]+=leap(a.year);

    for(i=0;i<a.month-1;ret+=days[i++]);

    days[1]=28;

    return (ret+a.day-1)*24+a.hour+1;

}



struct data1

{

    __int64 hour;

    __int64 v;

}need[100099];



struct data2

{

    __int64 ben;

    __int64 hour;

}qq[100999];



__int64 cmp(data1 a,data1 b)

{

    return a.hour<b.hour;

}



int main()

{

    __int64 n,m;

    while(scanf("%I64d%I64d",&n,&m))

    {

        if(n==0&&m==0)return 0;

        

        __int64 i,j,year,mon,day,time;

        

        char mm[9];

        DD temp;

        for(i=1;i<=n;i++)

        {

            scanf("%s",mm);

            for(j=1;j<=12;j++)

            {

                if(strcmp(Month[j],mm)==0){

                    temp.month=j;

                    break;

                }

            }

            scanf("%I64d%I64d%I64d",&temp.day,&temp.year,&temp.hour);

            __int64 temp1=need[i].hour=data__int64(temp);

            scanf("%I64d",&need[i].v);

        }

        

        sort(&need[1],&need[n+1],cmp);

        

        __int64 max,pri,cost;

        scanf("%I64d%I64d",&max,&pri);

        

        __int64 start,top,tail;

        top=tail=start=1;

        

        

        __int64 all=0;

        for(i=1;i<=m;i++)

        {

            scanf("%I64d",&cost);

            while(top<tail&&qq[tail-1].ben+(i-qq[tail-1].hour)*pri>=cost)tail--;

            

            qq[tail].ben=cost;qq[tail].hour=i;tail++;

            

            while(start<=n&&need[start].hour==i)

            {

                while((top<tail-1)&&(qq[top].hour+max<need[start].hour)) top++;  



                __int64 temp=need[start].hour-qq[top].hour;



                all+=(qq[top].ben+(need[start].hour-qq[top].hour)*pri)*need[start].v;

                start++;

            }

        }

        

        printf("%I64d\n",all);

    }

}

你可能感兴趣的:(HDU)