• HDU 4122Alice's mooncake shop解题报告


    这道题要用到单调队列,我们从给出的样例能够看出,区间上很长的一段对当前的决策来说是毫无意义的,最明显的就是比当前的值大的那些值,其实这个也有一点动态规划的思想在里面,我们保证了队首位置的值对当前来说是最优的,很显然这肯定是一个递增的队列,对于当前要加入队列中的元素,我们去掉对于其来说毫无意义的一些值,对于队列中的一个位置i如果其后的一个位置的j的最优值取在了i的位置,也就意味着cost[j]>cost[i]+(j-i)*S,那么对于其后的一个位置k如果有cost[j]+(k-j)*S<cost[k]不等式相加我们可以得到cost[k]>cost[i]+(k-i)*S,而且我们假设cost[j]-cost[i]-(j-i)*S=m以及cost[k]-cost[j]-(k-j)*S=n则cost[k]-cost[i]-(k-i)*S=m+n也就是说队列里的元素从队首至当前要插入的位置对于k来说的优先级别是递减的。也就是说,队首元素就是最优的元素。

    View Code
     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #define M 3000
     5 #define N 100005
     6 using namespace std;
     7 _int64 que[N];
     8 _int64 id[N];
     9 _int64 val[M];
    10 _int64 t[M];
    11 char mon[12][5]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
    12 _int64 getmon(char *s)
    13 {
    14     _int64 i;
    15     for(i=0;i<12;i++)
    16         if(!strcmp(s,mon[i]))
    17             return i;
    18 }
    19 _int64 day[12]={31,28,31,30,31,30,31,31,30,31,30,31};
    20 bool is(_int64 year)
    21 {
    22     if(year%400==0||(year%100&&year%4==0))
    23         return true;
    24     return false;
    25 }
    26 _int64 alltime(_int64 year,_int64 month,_int64 date,_int64 hour)
    27 {
    28     _int64 i,j;
    29     _int64 ans=0;
    30     for(i=2000;i<year;i++)
    31     {
    32         if(is(i))
    33             ans+=366;
    34         else
    35             ans+=365;
    36     }
    37     for(i=0;i<month;i++)
    38     {
    39         if(is(year)&&i==1)
    40             ans+=29;
    41         else
    42             ans+=day[i];
    43     }
    44     ans+=(date-1);
    45     ans*=24;
    46     ans+=hour;
    47     return ans;
    48 }
    49 int main()
    50 {
    51     char mo[5];
    52     _int64 n,m;
    53     _int64 year,date,hour,month;
    54     _int64 S,cost,T;
    55     _int64 ans;
    56     _int64 i;
    57     while(scanf("%I64d%I64d",&n,&m)&&(n||m))
    58     {
    59         for(i=0;i<n;i++)
    60         {
    61             scanf("%s%I64d%I64d%I64d%I64d",mo,&date,&year,&hour,&val[i]);
    62             month=getmon(mo);
    63             t[i]=alltime(year,month,date,hour);
    64         }
    65         scanf("%I64d%I64d",&T,&S);
    66         _int64 top,tail;
    67         _int64 fir;
    68         top=tail=fir=0;
    69         ans=0;
    70         for(i=0;i<m;i++)
    71         {
    72             scanf("%I64d",&cost);
    73             while(top<tail&&(que[tail-1]+(i-id[tail-1])*S)>=cost)
    74                 tail--;
    75             que[tail]=cost;
    76             id[tail++]=i;
    77             while(fir<n&&t[fir]==i)
    78             {
    79                 while(top<tail-1&&id[top]+T<t[fir])
    80                     top++;
    81                 ans+=val[fir]*(que[top]+(t[fir]-id[top])*S);
    82                 fir++;
    83             }
    84         }
    85         printf("%I64d\n",ans);
    86     }
    87     return 0;
    88 }
  • 相关阅读:
    创业4
    创业3
    PowerBI开发 第十四篇:使用M公式添加列
    PowerBI开发 第十三篇:增量刷新
    PowerBI开发 第十二篇:钻取
    SSIS 连接数据
    SSIS 调试和故障排除
    SQL Server 日志和代理的错误日志
    SSIS 检查点(CheckPoint)内幕
    SSIS 如何处理逻辑类型的转换?
  • 原文地址:https://www.cnblogs.com/caozhenhai/p/2741551.html
Copyright © 2020-2023  润新知