单调队列——HDU4122

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

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

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

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

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);
    }
}
原文地址:https://www.cnblogs.com/huhuuu/p/2482809.html