hdu 4122(RMQ)2011福州现场赛B题

题意:月饼店卖月饼有一些预定月饼店在2000年一月一号0点开张k小时。每小时做出来的月饼价格不一样,月饼能保存若干小时每小时花费都告诉你。让你求月饼店完成所有订单的最小成本。

思路:这道题本身思路不难,我们知道月饼保存费用和每天做月饼的费用,我们就能算出来每天做月饼的成本,然后在这个数组上RMQ就可以了。就是日起处理比较麻烦,具体还是见代码吧。

代码如下:

  1 #include <cstdlib>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cmath>
  5 #include <iostream>
  6 #include <algorithm>
  7 #include <queue>
  8 #include <stack>
  9 #include <vector>
 10 
 11 using namespace std;
 12 
 13 typedef pair<int, int> pii;
 14 typedef long long ll;
 15 
 16 const int INF = 0x3f3f3f3f;
 17 const int LEN = 100010;
 18 ll que[2*LEN], ad[2*LEN], tb[LEN];
 19 int day[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 20 struct CS {
 21   char mon[5];
 22   int y, d, h, num;
 23 };
 24 CS con[5000+10];
 25 
 26 
 27 bool jy(int y) {
 28   return ((y%4==0 && y%100!=0) || y%400==0);
 29 }
 30 
 31 int changedata(char mon[], int d, int y, int h) {
 32   int ret = 0;
 33   if(y < 2000) return INF;
 34   for(int i=2000; i<y; i++) {
 35     if(jy(i)) ret += 366;
 36     else ret += 365;
 37   }
 38   int mtag = -1000;
 39   if(!strcmp(mon, "Jan")) {
 40     mtag = 1;
 41   } else if(!strcmp(mon, "Feb")) {
 42     mtag = 2;
 43   } else if(!strcmp(mon, "Mar")) {
 44     mtag = 3;
 45   } else if(!strcmp(mon, "Apr")) {
 46     mtag = 4;
 47   } else if(!strcmp(mon, "May")) {
 48     mtag = 5;
 49   } else if(!strcmp(mon, "Jun")) {
 50     mtag = 6;
 51   } else if(!strcmp(mon, "Jul")) {
 52     mtag = 7;
 53   } else if(!strcmp(mon, "Aug")) {
 54     mtag = 8;
 55   } else if(!strcmp(mon, "Sep")) {
 56     mtag = 9;
 57   } else if(!strcmp(mon, "Oct")) {
 58     mtag = 10;
 59   } else if(!strcmp(mon, "Nov")) {
 60     mtag = 11;
 61   } else if(!strcmp(mon, "Dec")){
 62     mtag = 12;
 63   }
 64   for(int i=1; i<mtag; i++) {
 65     ret += day[i];
 66     if(i==2 && jy(y)) ret ++;
 67   }
 68   ret += d-1;
 69   ret *= 24;
 70   ret += h;
 71   return ret;
 72 }
 73 
 74 //RMQ
 75 ll dp[LEN][20], mm[LEN];
 76 void initRMQ(int n, ll b[]) {
 77   mm[0] = -1;
 78   for(int i=1; i<=n; i++) {
 79     mm[i] = ((i&(i-1)) == 0) ? mm[i-1]+1 : mm[i-1];
 80     dp[i][0] = b[i];
 81   }
 82   for(int j=1; j<=mm[n]; j++)
 83     for(int i=1; i+(1<<j)-1 <= n; i++)
 84       dp[i][j] = min(dp[i][j-1], dp[i+(1 << (j-1))][j-1]);
 85 }
 86 
 87 ll rmq(int x, int y) {
 88   ll k = mm[y-x+1];
 89   return min(dp[x][k], dp[y-(1 << k)+1][k]);
 90 }
 91 
 92 int main()
 93 {
 94 #ifdef LOCALL
 95   freopen("in.txt","r",stdin);
 96   //freopen("out","w",stdout);
 97 #endif
 98 
 99   int save, cost, n, m;
100   while(scanf("%d%d", &n, &m)!=EOF) {
101     if(!n && !m) break;
102     for(int i=0; i<n; i++) {
103       scanf("%s%d%d%d%d", con[i].mon, &con[i].d, &con[i].y, &con[i].h, &con[i].num);
104     }
105     scanf("%d%d", &save, &cost);
106     for(int i=0; i<m; i++) {
107       scanf("%I64d", &que[i]);
108       ad[i] = (m-i)*cost;
109     }
110     for(int i=0; i<m; i++) {
111       tb[i+1] =  ad[i]+que[i];
112     }
113     initRMQ(m, tb);
114     ll ans = 0;
115     for(int i=0; i<n; i++) {
116       int locd = changedata(con[i].mon, con[i].d, con[i].y, con[i].h);
117       if(locd > m) {continue;}
118       ans += (rmq((locd-save+1>=1?locd-save+1:1), (locd+1<=m?locd+1:m))-ad[locd])*con[i].num;
119     }
120     printf("%I64d\n", ans);
121   }
122   return 0;
123 }
View Code

 

posted @ 2014-03-24 00:20  张小豪  阅读(127)  评论(0编辑  收藏  举报