bzoj1855: [Scoi2010]股票交易

背包

 

感觉省选怎么会考这么简单的东西呢 无聊去网上搜了一下 发现原来正解是单调队列来优化呀

不过带个log问题也不大

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<string>
 7 
 8 using namespace std;
 9 
10 void setIO(const string& a) {
11     freopen((a+".in").c_str(), "r", stdin);
12     freopen((a+".out").c_str(), "w", stdout);
13 }
14 
15 const int N = 2010, INF = 0x3f3f3f3f;
16 
17 int f[N][N], g[N];
18 
19 template<typename Q> void maxit(Q& x, const Q& y) {
20     if(x < y) x = y;
21 }
22 
23 int main() {
24     
25     int n, maxp, w, ap, bp, as, bs;
26     scanf("%d%d%d", &n, &maxp, &w);
27     
28     memset(f, -0x3f, sizeof f);
29     
30     f[1][0] = 0;
31     
32     for(int sum, ok, k, i = 1; i <= n; i++) {
33         scanf("%d%d%d%d", &ap, &bp, &as, &bs);
34         memcpy(g, f[i], sizeof g);
35         int tmr = min(i + 1 + w, n + 1);
36         for(ok = 1, sum = 0, k = 1; ok; k <<= 1) {
37             if(sum + k <= as) sum += k;
38             else k = as - sum, ok = 0;
39             for(int j = maxp; j >= 0; j--) if(g[j] > -INF) {// buy
40                 if(j + k <= maxp) maxit(g[j + k], g[j] - ap * k);
41             }
42         }
43 //        memcpy(g, f[i], sizeof g);
44         for(ok = 1, sum = 0, k = 1; ok; k <<= 1) {
45             if(sum + k <= bs) sum += k;
46             else k = bs - sum, ok = 0;
47             for(int j = 0; j <= maxp; j++) if(g[j] > -INF) {// sell
48                 if(j - k >= 0) maxit(g[j - k], g[j] + bp * k);
49             }
50         }
51         for(int j = 0; j <= maxp; j++) {
52             maxit(f[i + 1][j], f[i][j]);
53             maxit(f[tmr][j], g[j]);
54         }        
55     }
56     int ans = 0;
57     for(int i = 0; i <= maxp; i++) ans = max(ans, f[n + 1][i]);
58     printf("%d\n", ans);
59     
60     return 0;
61 }

 

posted @ 2015-11-30 10:47  Showson  阅读(197)  评论(0编辑  收藏  举报