HDU 4122:Alice's mooncake shop RMQ(2011 Asia Fuzhou Regional Contest )

Alice's mooncake shop

题目链接:

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

题意:

Alice开了一家24小时营业的月饼店,2000年1月1日0点是第一个小时,每个整点可以造月饼且造价不同,造的月饼可以当天卖掉或者储存T天(每天每个月饼花费S元),现在Alice有一些订单,求满足这些订单的最少成本。

题解:

先把每天制造一个月饼的成本加上S*( n-i ),然后第 i 天的成本就是[i-T,i]间的最小值减去i*S

代码

 
#include<stdio.h>
#include<string>
#include<iostream>
using namespace std;
const int N=2501;
const int M=1e5+1;
int mmax(int x,int y)
{
    return x>y?x:y;
}
long long mmin(long long x,long long y)
{
    return x<y?x:y;
}
long long dpmin[M][20],need[N],S;
bool Leap_Year(int x)
{
    if(x%400==0||(x%4==0&&(x%100!=0)))return true;
    return false;
} 
int month[13]={0,31,28,31,30,31,30,31,31,30,31,30,31},time[N];
int Find_Time(int y,int m,int d,int h)
{
    int sum=0;
    for(int i=2000;i<y;++i)
    {
        if(Leap_Year(i))sum+=366;
        else sum+=365;
    }
    for(int i=1;i<m;++i)
    {
        sum+=month[i];
        if(i==2&&Leap_Year(y))sum++;
    }
    sum+=(d-1);
    sum*=24;
    sum+=h+1;
    return sum;
}
long long cost[M];
string s;
void Make_Rmq(int m)
{
    for(int i=1;i<=m;++i)
    {
        dpmin[i][0]=cost[i]+S*(long long)(m-i);
    }
    for(int j=1;(1<<j)<=m;++j)
    for(int i=1;i+(1<<j)-1<=m;++i)
    {
        dpmin[i][j]=mmin(dpmin[i][j-1],dpmin[i+(1<<j-1)][j-1]);
    }
}
long long Get_Rmq(int u,int v)
{
    int k=0;
    while((1<<k+1)<=v-u+1)
    k++;
    return mmin(dpmin[u][k],dpmin[v-(1<<k)+1][k]);
}
void solve()
{
    int n,m,mon,d,y,h,T;
    while(~scanf("%d%d",&n,&m)&&(n||m))
    {
        for(int i=1;i<=n;++i)
        {
            cin>>s;
            if(s=="Jan")mon=1;
            else if(s=="Feb")mon=2;
            else if(s=="Mar")mon=3;
            else if(s=="Apr")mon=4;
            else if(s=="May")mon=5;
            else if(s=="Jun")mon=6;
            else if(s=="Jul")mon=7;
            else if(s=="Aug")mon=8;
            else if(s=="Sep")mon=9;
            else if(s=="Oct")mon=10;
            else if(s=="Nov")mon=11;
            else mon=12;
            scanf("%d%d%d%lld",&d,&y,&h,&need[i]);
            time[i]=Find_Time(y,mon,d,h);
        }
        scanf("%d%lld",&T,&S);
        for(int i=1;i<=m;++i)
        {
            scanf("%lld",&cost[i]);
        }
        Make_Rmq(m);
        long long res=0;
        for(int i=1;i<=n;++i)
        {
            res+=Get_Rmq(mmax(1,time[i]-T),time[i])*need[i]-(long long)(m-time[i])*S*need[i];
        }
        printf("%lld
",res);
    }
}
int main()
{
    solve();    
    return 0;
}
原文地址:https://www.cnblogs.com/kiuhghcsc/p/5745709.html