zoukankan      html  css  js  c++  java
  • hdu4122 制作月饼完成订单的最小花费

    题意:
          有一个加工厂加工月饼的,这个工厂一共开业m小时,2000年1月1日0点是开业的第一个小时,每个小时加工月饼的价钱也不一样,然后每个月饼的保质期都是t天,因为要放在冰箱里保存,所以在保质期期间每天每个月饼的花费是s,他接到了n个订单,问你完成这n个订单的最小花费是多少?


    思路:
         想到这样一个性质,在一个序列里面某一个位置的值是由他前面的某一个范围中的一个得到的,而且我们要当前这个位置最小(或者最大),这样的问题可以用单调队列解决,这个题目我们可以弄一个递增的单调队列,小的那头要保证不过期,大的那头要保证递增,这样就ok了,还有对于这个题目,我的方法是吧所有的订单日期全都处理成小时(就是于题目中的m对应)去做,这样能清晰点,还有就是有两个小提示,订单当天做也来得及,还有一个就是两个订单的日期可能相同,别的没什么了,具体细节看下面代码。
          


    #include<map>
    #include<string>
    #include<stdio.h>
    #include<string.h>


    #define N 2500 + 50


    using namespace std;


    map<__int64 ,__int64>mark;
    map<string ,int>mk;
    __int64 ry[13] = {0 ,31 ,29 ,31 ,30 ,31 ,30 ,31 ,31 ,30 ,31 ,30 ,31};
    __int64 py[13] = {0 ,31 ,28 ,31 ,30 ,31 ,30 ,31 ,31 ,30 ,31 ,30 ,31};
    __int64 C[110000] ,node[N];
    __int64 hash[110000];
    int Q[110000];
    __int64 tou ,wei;


    void DB()
    {
       mk["Jan"] = 1; mk["Feb"] = 2; mk["Mar"] = 3;
       mk["Apr"] = 4; mk["May"] = 5; mk["Jun"] = 6;
       mk["Jul"] = 7; mk["Aug"] = 8; mk["Sep"] = 9;
       mk["Oct"] = 10; mk["Nov"] = 11; mk["Dec"] = 12;
    }


    bool jude(__int64 now)
    {
       return now % 400 == 0 || now % 4 == 0 && now % 100 != 0;
    }


    void insert(int t ,__int64 tt,__int64 cost)
    {
       for(int i = wei ;i > tou ;i --)
       {
          if(C[t] <= (__int64)(t - Q[wei]) * cost + C[Q[wei]])
          wei --;
          else break;
       }
       Q[++wei] = t;
       for(int i = tou + 1;i <= wei ;i ++)
       if(t - Q[i] > tt) tou ++;
    }
       


    int main ()
    {
       int n ,m ,a ,i;
       __int64 y ,r ,h ,t ,cost;
       char mouse[10];
       DB();
       while(~scanf("%d %d" ,&n ,&m) && n + m)
       {
          mark.clear();
          for(i = 1 ;i <= n ;i ++)
          {
             scanf("%s %I64d %I64d %I64d %I64d" ,mouse ,&r ,&y ,&h ,&node[i]);
             __int64 now = mk[mouse] * 10000 + y * 1000000 + r * 100 + h * 1;      
             if(mark[now]) node[mark[now]] += node[i];
             else mark[now] = i;   
          }
          memset(hash ,0 ,sizeof(hash));
          __int64 nn = 2000,yy = 1 ,rr = 1,ss = 0;
          if(mark[nn*1000000+yy*10000+rr*100+ss*1])
          {
             hash[1] = mark[nn*1000000+yy*10000+rr*100+ss*1];
          }
          for(i = 2 ;i <= m ;i ++)
          {
             ss ++;
             if(ss == 24) {ss = 0 ,rr ++;}
             if(jude(nn) && rr == ry[yy] + 1 || !jude(nn) && rr == py[yy] + 1)
             {yy ++ ,rr = 1;}
             if(yy == 13) {yy = 1 ;nn ++;}
             if(mark[nn*1000000+yy*10000+rr*100+ss*1])
             hash[i] = mark[nn*1000000+yy*10000+rr*100+ss*1]; 
          }
          scanf("%I64d %I64d" ,&t ,&cost); 
          for(i = 1 ;i <= m ;i ++)
          scanf("%I64d" ,&C[i]);
          tou = wei = 0;
          __int64 Ans = 0;
          for(i = 1 ;i <= m ;i ++)
          {    
             insert(i ,t ,cost);
             if(hash[i])
             {  
                int T = Q[tou + 1];
                Ans +=  C[T] * node[hash[i]] + node[hash[i]] * (__int64)(i - T) * cost;
             }   
          }
          printf("%I64d " ,Ans);      
          
       }
       return 0;
    }
          
             
             
             
             
          
       
       
       
       

















  • 相关阅读:
    ThinkDev组件库 开篇
    使用 CodeIgniter 框架快速开发 PHP 应用(六)
    使用 CodeIgniter 框架快速开发 PHP 应用(五)
    jQuery EasyUI 的截图插件(imgAreaSelect)用法
    细说UI线程和Windows消息队列
    ASP.NET MVC2 异常处理机制中令人费解的HTTP 500错误
    从了解到深入——剖析WF4的数据流
    .NET 4.0中数组的新增功能
    成功就是把自己的特长发挥得淋漓尽致(更新)
    WPF4数据绑定应用之“创建具有多种显示效果的字串”
  • 原文地址:https://www.cnblogs.com/csnd/p/12062630.html
Copyright © 2011-2022 走看看