zoukankan      html  css  js  c++  java
  • hdu4122(模拟+单调队列+处理方式)

    模拟题就是有坑!!!!见代码注释

    题意:Alice开了家月饼店,现有2500笔订单,订单包括某小时(2000年1月1日0点算第1个小时的开始)和需要的月饼数量。然后给你前100000小时的信息,包括第i个小时做1个饼的花费cost[i]。然后给你月饼的保质期T(说明订单i只能买[order[i].hour-T , order[i].hour ]这个区间生产的饼)和保存1小时的花费S,让你求最小的花费满足所有订单。

    分析:首先要把订单的时间转化成自2000年1月1日0点开始的第几小时,由于最多100000小时,所以最大到2012年的样子。然后维护一个最小值的单调队列。

    //#pragma comment(linker, "/STACK:102400000")
    #include<cstdlib>
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<list>
    #include<queue>
    #include<stack>
    #include<vector>
    #define tree int o,int l,int r
    #define lson o<<1,l,mid
    #define rson o<<1|1,mid+1,r
    #define lo o<<1
    #define ro o<<1|1
    #define pb push_back
    #define mp make_pair
    #define ULL unsigned long long
    #define LL long long
    #define inf 0x7fffffff
    #define eps 1e-7
    #define N 2509
    #define M 100009
    using namespace std;
    int m,n,T,t,s;
    int ti[N],num[N];
    LL ans;
    int q[M],c[M];
    char tr[13][10]= { "","Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
    int mon[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
    int get(int k)
    {
        char str[10];
        int d,y,h,m;
        scanf("%s%d%d%d%d",str,&d,&y,&h,&num[k]);
        for (int i=1; i<13; ++i )
            if(strcmp(tr[i],str)==0)
            {
                m=i;
                break;
            }
        int ans=0;
        for(int i=2000; i<y; i++)
        {
            if((i%400==0)||(i%100!=0&&i%4==0))
                ans+=366;
            else
                ans+=365;
        }
        if((y%400==0)||(y%100!=0&&y%4==0))
            mon[2]=29;
        else
            mon[2]=28;
        for(int i=1; i<m; i++)
            ans+=mon[i];
        ans+=d-1;
        ans*=24;
        ans+=h+1;
        return ans;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("ex.in","r",stdin);
    #endif
        while(scanf("%d%d%*c",&n,&m)==2)
        {
            if(!n&&!m)return 0;
            for (int i=0; i<n; ++i )
            {
                ti[i]=get(i);
            }
            scanf("%d%d",&t,&s);
            int l=0,r=0,cnt=0;
            ans=0;
            for (int i=1; i<=max(m,ti[n-1]); ++i )//超出m的订单也是可以的
            {
                if(i<=m)
                {
                    scanf("%d",&c[i]);
                    while(l<r&&((LL)i-q[r-1])*s+c[q[r-1]]>=c[i])
                        r--;
                    q[r++]=i;
                }
                while(l<r&&i-q[l]>t)l++;
                while(i==ti[cnt])//题目中说是升序,但是有相等的,(WA)
                {
                    ans+=((LL)(i-q[l])*s+c[q[l]])*num[cnt];
                    cnt++;
                }
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    排序链表
    给定两个字符串 s 和 t,它们只包含小写字母。 字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。 请找出在 t 中被添加的字母。
    给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。
    快速排序之三路快排
    双向链表实现
    删除链表重复元素
    链表是否是回文串
    链表逆序
    排序之归并排序
    线性表之链表实现
  • 原文地址:https://www.cnblogs.com/sbaof/p/3380216.html
Copyright © 2011-2022 走看看