HDU 4122 Alice's mooncake shop(RMQ:动态最值)

来源:互联网 发布:大数据概念股 编辑:程序博客网 时间:2024/05/16 11:19

HDU 4122 Alice's mooncake shop(RMQ:动态最值)

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

题意:

        Alice has opened up a 24-hour mooncake shop. She always gets a lot of orders. Only when the time is K o’clock sharp( K = 0,1,2 …. 23) she can make mooncakes, and We assume that making cakes takes no time. Due to the fluctuation of the price of the ingredients, the cost of a mooncake varies from hour to hour. She can make mooncakes when the order comes,or she can make mooncakes earlier than needed and store them in a fridge. The cost to store a mooncake for an hour is S and the storage life of a mooncake is T hours. She now asks you for help to work out a plan to minimize the cost to fulfill the orders.

Input
The input contains no more than 10 test cases. 
For each test case:
The first line includes two integers N and M. N is the total number of orders. M is the number of hours the shop opens. 
The next N lines describe all the orders. Each line is in the following format:

month date year H R

It means that on a certain date, a customer orders R mooncakes at H o’clock. “month” is in the format of abbreviation, so it could be "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov" or "Dec". H and R are all integers. 
All the orders are sorted by the time in increasing order. 
The next line contains T and S meaning that the storage life of a mooncake is T hours and the cost to store a mooncake for an hour is S.
Finally, M lines follow. Among those M lines, the ith line( i starts from 1) contains a integer indicating the cost to make a mooncake during the ith hour . The cost is no more than 10000. Jan 1st 2000 0 o'clock belongs to the 1st hour, Jan 1st 2000 1 o'clock belongs to the 2nd hour, …… and so on.

(0<N <= 2500; 0 < M,T <=100000; 0<=S <= 200; R<=10000 ; 0<=H<24)

The input ends with N = 0 and M = 0.

分析:

        大致思想就是读入时间,然后换算成从0M-1之间的第x个小时,然后在【x-Tx】区间内用RMQ查找生产月饼的最小成本。然后用最小成本乘以月饼数即是该条order的成本了。

        不过这里查询最小值函数getMin返回的是最小成本的编号i,而且比较最小值的函数不是静态比较而是动态比较,并不是单纯的比较值而且要考虑S(即保存成本)和两者之间的时间差。

        例如在第3小时生成的成本是4,在第5小时生产的成本是6,但是保存月饼每小时开销是2.那么3小时和5小时比较的情况是(假设生成1块月饼):3小时生成了一块月饼花费了4,但是需要保存到5小时又花费了4的保存成本,所以一共花费了8的成本。但是5小时可以直接生成月饼花费6不用保存,所以最小值时5小时。

AC代码:140ms

<span style="font-size:18px;"><span style="font-size:18px;">#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int getmonth(char s[]){    if(strcmp(s,"Jan")==0)return 1;    else if(strcmp(s,"Feb")==0)return 2;    else if(strcmp(s,"Mar")==0)return 3;    else if(strcmp(s,"Apr")==0)return 4;    else if(strcmp(s,"May")==0)return 5;    else if(strcmp(s,"Jun")==0)return 6;    else if(strcmp(s,"Jul")==0)return 7;    else if(strcmp(s,"Aug")==0)return 8;    else if(strcmp(s,"Sep")==0)return 9;    else if(strcmp(s,"Oct")==0)return 10;    else if(strcmp(s,"Nov")==0)return 11;    else 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;    return false;}struct node{    char mon[10];    int y,m,d,h;    int R;    int index;//表示读入的时间是从2000年1月1日0时算起的第几个小时,从1开始计数    void input()    {        scanf("%s%d%d%d%d",mon,&d,&y,&h,&R);        if(y<2000)//非法        {            index = -1;            return ;        }        int m = getmonth(mon);        index=0;        for(int i=2000;i<y;i++)//整年之差        {            if(isleap(i))index += 366*24;            else index +=365*24;        }        for(int i=1;i<m;i++)//整月之差        {            index += days[i]*24;        }        if(isleap(y) && m>2)index +=24;//最后一年也是闰年且超过了2月        index += (d-1)*24;//整日之差        index +=h+1;//小时之差,不过index从1开始计数,所以是h+1    }}nodes[3000];const int MAXN=100000+1000;int a[MAXN];//a[i]表示第i小时做月饼的初始成本int dmin[MAXN][20];int n,m,T,S;int minv(int i,int j){    if(i==j)return i;    else if(i<j)    {        return a[i]+(j-i)*S<=a[j]?i:j;    }    else    {        return a[j]+(i-j)*S<=a[i]?j:i;    }}void initMin(int n){    for(int i=1;i<=n;i++)dmin[i][0]=i;    for(int j=1;(1<<j)<=n;j++)        for(int i=1;i+(1<<j)-1<=n;i++)        {            dmin[i][j] = minv(dmin[i][j-1] , dmin[i+(1<<(j-1))][j-1]);        }}int getMin(int L,int R){    int k=0;    while((1<<(k+1))<=R-L+1)k++;    return minv(dmin[L][k] , dmin[R-(1<<k)+1][k]);}int main(){    while(scanf("%d%d",&n,&m)==2&&n&&m)    {        for(int i=1;i<=n;i++)            nodes[i].input();        scanf("%d%d",&T,&S);        for(int i=1;i<=m;i++)            scanf("%d",&a[i]);        initMin(m);        long long ans=0;        for(int i=1;i<=n;i++)        {            int index = nodes[i].index;            if(index<0||index>m)continue;            int min_i = getMin(max(1,index-T),index);            ans += (a[min_i]+(index-min_i)*S)*nodes[i].R;        }        printf("%I64d\n",ans);    }    return 0;}</span></span>


0 0
原创粉丝点击