zoukankan      html  css  js  c++  java
  • HDU 4122 Alice's mooncake shop --RMQ

    题意: 一个月饼店做月饼,总营业时间m小时,只能在整点做月饼,可以做无限个,不过在不同的时间做月饼的话每个月饼的花费是不一样的,假设即为cost[i],再给n个订单,即为在某个时间要多少个月饼,时间从2000年1月1日0时开始计算,必须在每个订单的时间之前完成这么多月饼,月饼还有保质期T小时以及保存费用S每小时,现在问满足这n个点的最小成本是多少。

    解法: 

    因为月饼有保质期T,所以第i个月饼只能在[Ti-T+1,Ti]时间内做好。
    如果时间j有订单,假设在时间i做月饼是最好的,那么这个订单每个月饼的
    花费为 cost[i] + (j-i)*S = cost[i]-i*S + j*S, 由于j不变,所以求cost[i]-i*S的
    最小值即可,即求[Ti-T+1,Ti]内的cost[i]-i*S最小值,求区间最小值我们用RMQ可以快速求出
    这里RMQ用了一个Log函数优化,使得到k的时间复杂度为O(1)
    这里的月份处理采用了kuangbin大神的模板,简洁又好用。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #define lll __int64
    using namespace std;
    #define N 100017
    
    lll d[N][21],cost[N];
    int LOG[N],n;
    
    int getmonth(char s[])
    {
        if(strcmp(s,"Jan") == 0) return 1;
        if(strcmp(s,"Feb") == 0) return 2;
        if(strcmp(s,"Mar") == 0) return 3;
        if(strcmp(s,"Apr") == 0) return 4;
        if(strcmp(s,"May") == 0) return 5;
        if(strcmp(s,"Jun") == 0) return 6;
        if(strcmp(s,"Jul") == 0) return 7;
        if(strcmp(s,"Aug") == 0) return 8;
        if(strcmp(s,"Sep") == 0) return 9;
        if(strcmp(s,"Oct") == 0) return 10;
        if(strcmp(s,"Nov") == 0) return 11;
        if(strcmp(s,"Dec") == 0) return 12;
    }
    int days[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    bool isleap(int y)
    {
        if(y % 400 == 0 || (y % 100 != 0 && y%4 == 0))return true;
        else return false;
    }
    struct Node
    {
        char mon[10];
        int d,y,h,R;
        lll tim;
        void input()
        {
            scanf("%s%d%d%d%d",mon,&d,&y,&h,&R);
            tim = 0;
            for(int i = 2000;i < y;i++)
            {
                if(isleap(i)) tim += 366*24;
                else          tim += 365*24;
            }
            for(int i = 1;i < getmonth(mon);i++)
                tim += days[i]*24;
            if(isleap(y) && getmonth(mon) > 2) tim += 24;
            tim += (d-1)*24;
            tim += h+1;
        }
    }order[2704];
    
    void RMQ_init(int m)
    {
        int i,j;
        for(i=1;i<=m;i++)
            d[i][0] = cost[i];
        for(j=1;(1<<j)<=m;j++)
        {
            for(i=1;i+(1<<j)-1<=m;i++)
                d[i][j] = min(d[i][j-1],d[i+(1<<(j-1))][j-1]);
        }
    }
    void getLog(int n)
    {
        for(int i=0;i<=n;i++)
            LOG[i] = (int)(log((double)i)/log(2.0));
    }
    lll RMQ(int l,int r)
    {
        int k = LOG[r-l+1];
        return min(d[l][k],d[r-(1<<k)+1][k]);
    }
    
    int main()
    {
        int n,m,T,S,i,j;
        while(scanf("%d%d",&n,&m)!=EOF && n+m)
        {
            getLog(m);
            for(i=1;i<=n;i++)
                order[i].input();
            scanf("%d%d",&T,&S);
            for(i=1;i<=m;i++)
            {
                scanf("%I64d",&cost[i]);
                cost[i] -= i*S;
            }
            RMQ_init(m);
            lll ans = 0;
            for(i=1;i<=n;i++)
            {
                if(order[i].tim < 0 || order[i].tim > m) continue;
                int L = max(1LL,order[i].tim - T + 1);
                int R = order[i].tim;
                lll MN = RMQ(L,R);
                ans += (MN+order[i].tim*S)*order[i].R;
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    telnet连接ip
    完成端口————留着看
    mysql设置最大连接数量
    前端页面唯一字符串生成(Js)UUID
    java加密MD5实现及密码验证
    cookie中存取中文字符
    自定义标签——带标签体
    简单讨论数据类型(byte)强制转化后的数值变化规律
    般若波罗蜜多心经(转载)
    table 表头固定
  • 原文地址:https://www.cnblogs.com/whatbeg/p/4101872.html
Copyright © 2011-2022 走看看